summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt181
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/camera/Front.xml142
-rw-r--r--indra/newview/app_settings/camera/Rear.xml142
-rw-r--r--indra/newview/app_settings/camera/Side.xml142
-rw-r--r--indra/newview/app_settings/cmd_line.xml9
-rw-r--r--indra/newview/app_settings/commands.xml27
-rw-r--r--indra/newview/app_settings/high_graphics.xml2
-rw-r--r--indra/newview/app_settings/key_bindings.xml (renamed from indra/newview/app_settings/keys.xml)144
-rw-r--r--indra/newview/app_settings/low_graphics.xml2
-rw-r--r--indra/newview/app_settings/mid_graphics.xml2
-rw-r--r--indra/newview/app_settings/settings.xml392
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl683
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl123
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl145
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl8
-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.glsl128
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl130
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cofF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl113
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl52
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/indirect.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl923
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl229
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl104
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl166
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl55
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl221
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl214
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl521
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl101
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl52
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl103
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl85
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl210
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/srgbF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl)38
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl84
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl77
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleV.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/treeV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl134
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl42
-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/gammaF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/transportF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/indirect.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl475
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyF.glsl199
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl540
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl134
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl226
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl292
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl117
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl135
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyV.glsl213
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl4
-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.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/srgb.glsl)36
-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/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/genSkyShV.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/indirect.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl291
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl33
-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/shadowCubeV.glsl50
-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/skyV.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl177
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl287
-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/sunLightV.glsl41
-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/underWaterF.glsl115
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterF.glsl174
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterV.glsl95
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/lightV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl31
-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.txt11
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml2
-rw-r--r--indra/newview/featuretable.txt12
-rw-r--r--indra/newview/featuretable_linux.txt13
-rw-r--r--indra/newview/featuretable_mac.txt13
-rw-r--r--indra/newview/icons/release/secondlife.icnsbin228390 -> 113020 bytes
-rw-r--r--indra/newview/icons/release/secondlife.icobin77552 -> 32988 bytes
-rw-r--r--indra/newview/icons/release/secondlife_128.pngbin15184 -> 5320 bytes
-rw-r--r--indra/newview/icons/release/secondlife_16.pngbin1009 -> 669 bytes
-rw-r--r--indra/newview/icons/release/secondlife_256.BMPbin196662 -> 131128 bytes
-rw-r--r--indra/newview/icons/release/secondlife_256.pngbin47740 -> 11572 bytes
-rw-r--r--indra/newview/icons/release/secondlife_32.pngbin2237 -> 1283 bytes
-rw-r--r--indra/newview/icons/release/secondlife_48.pngbin3748 -> 1958 bytes
-rw-r--r--indra/newview/icons/release/secondlife_512.pngbin154396 -> 26697 bytes
-rw-r--r--indra/newview/installers/windows/install_icon.BMPbin262198 -> 131128 bytes
-rw-r--r--indra/newview/installers/windows/install_icon.icobin367958 -> 32988 bytes
-rw-r--r--indra/newview/installers/windows/uninstall_icon.BMPbin262198 -> 131128 bytes
-rw-r--r--indra/newview/installers/windows/uninstall_icon.icobin367958 -> 32988 bytes
-rw-r--r--indra/newview/linux_tools/client-readme.txt4
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh10
-rw-r--r--indra/newview/llaccountingcostmanager.cpp4
-rw-r--r--indra/newview/llaccountingcostmanager.h6
-rw-r--r--indra/newview/llagent.cpp294
-rw-r--r--indra/newview/llagent.h25
-rw-r--r--indra/newview/llagentbenefits.cpp236
-rw-r--r--indra/newview/llagentbenefits.h88
-rw-r--r--indra/newview/llagentcamera.cpp202
-rw-r--r--indra/newview/llagentcamera.h55
-rw-r--r--indra/newview/llagentwearables.cpp18
-rw-r--r--indra/newview/llaisapi.cpp48
-rw-r--r--indra/newview/llaisapi.h4
-rw-r--r--indra/newview/llappcorehttp.cpp22
-rw-r--r--indra/newview/llappdelegate-objc.mm2
-rw-r--r--indra/newview/llappearancemgr.cpp82
-rw-r--r--indra/newview/llappearancemgr.h2
-rw-r--r--indra/newview/llappviewer.cpp771
-rw-r--r--indra/newview/llappviewer.h17
-rw-r--r--indra/newview/llappviewerlinux.cpp10
-rw-r--r--indra/newview/llappviewerlistener.cpp2
-rw-r--r--indra/newview/llappviewermacosx-for-objc.h1
-rw-r--r--indra/newview/llappviewermacosx.cpp9
-rw-r--r--indra/newview/llappviewerwin32.cpp119
-rw-r--r--indra/newview/llattachmentsmgr.cpp1
-rw-r--r--indra/newview/llattachmentsmgr.h2
-rw-r--r--indra/newview/llaudiosourcevo.cpp98
-rw-r--r--indra/newview/llaudiosourcevo.h4
-rw-r--r--indra/newview/llavataractions.cpp27
-rw-r--r--indra/newview/llavataractions.h2
-rw-r--r--indra/newview/llavatariconctrl.h1
-rw-r--r--indra/newview/llavatarlistitem.h2
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp13
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h2
-rw-r--r--indra/newview/llchannelmanager.cpp9
-rw-r--r--indra/newview/llchatbar.cpp4
-rw-r--r--indra/newview/llchathistory.cpp82
-rw-r--r--indra/newview/llchatitemscontainerctrl.cpp1
-rw-r--r--indra/newview/llchatitemscontainerctrl.h3
-rw-r--r--indra/newview/llchiclet.cpp5
-rw-r--r--indra/newview/llcofwearables.cpp21
-rw-r--r--indra/newview/llcolorswatch.h1
-rw-r--r--indra/newview/llcommandhandler.cpp2
-rw-r--r--indra/newview/llcommandlineparser.cpp31
-rw-r--r--indra/newview/llcompilequeue.cpp18
-rw-r--r--indra/newview/llcompilequeue.h3
-rw-r--r--indra/newview/llcontrolavatar.cpp119
-rw-r--r--indra/newview/llcontrolavatar.h7
-rw-r--r--indra/newview/llconversationlog.cpp50
-rw-r--r--indra/newview/llconversationlog.h6
-rw-r--r--indra/newview/llconversationmodel.cpp46
-rw-r--r--indra/newview/llconversationmodel.h2
-rw-r--r--indra/newview/llconversationview.cpp106
-rw-r--r--indra/newview/llconversationview.h6
-rw-r--r--indra/newview/llcurrencyuimanager.cpp32
-rw-r--r--indra/newview/llcurrencyuimanager.h2
-rw-r--r--indra/newview/lldaycyclemanager.cpp230
-rw-r--r--indra/newview/lldaycyclemanager.h84
-rw-r--r--indra/newview/lldensityctrl.cpp225
-rw-r--r--indra/newview/lldensityctrl.h104
-rw-r--r--indra/newview/lldirpicker.cpp4
-rw-r--r--indra/newview/lldirpicker.h2
-rw-r--r--indra/newview/lldrawable.cpp70
-rw-r--r--indra/newview/lldrawpool.cpp29
-rw-r--r--indra/newview/lldrawpool.h19
-rw-r--r--indra/newview/lldrawpoolalpha.cpp601
-rw-r--r--indra/newview/lldrawpoolalpha.h11
-rw-r--r--indra/newview/lldrawpoolavatar.cpp411
-rw-r--r--indra/newview/lldrawpoolavatar.h9
-rw-r--r--indra/newview/lldrawpoolbump.cpp47
-rw-r--r--indra/newview/lldrawpoolground.cpp15
-rw-r--r--indra/newview/lldrawpoolground.h2
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp13
-rw-r--r--indra/newview/lldrawpoolsimple.cpp199
-rw-r--r--indra/newview/lldrawpoolsky.cpp63
-rw-r--r--indra/newview/lldrawpoolsky.h4
-rw-r--r--indra/newview/lldrawpoolterrain.cpp121
-rw-r--r--indra/newview/lldrawpoolterrain.h4
-rw-r--r--indra/newview/lldrawpooltree.cpp14
-rw-r--r--indra/newview/lldrawpooltree.h5
-rw-r--r--indra/newview/lldrawpoolwater.cpp521
-rw-r--r--indra/newview/lldrawpoolwater.h18
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp612
-rw-r--r--indra/newview/lldrawpoolwlsky.h26
-rw-r--r--indra/newview/lldynamictexture.cpp29
-rw-r--r--indra/newview/lldynamictexture.h5
-rw-r--r--indra/newview/llenvadapters.cpp67
-rw-r--r--indra/newview/llenvadapters.h459
-rw-r--r--indra/newview/llenvironment.cpp3480
-rw-r--r--indra/newview/llenvironment.h477
-rw-r--r--indra/newview/llenvmanager.cpp721
-rw-r--r--indra/newview/llenvmanager.h349
-rw-r--r--indra/newview/llestateinfomodel.cpp3
-rw-r--r--indra/newview/llestateinfomodel.h2
-rw-r--r--indra/newview/lleventpoll.cpp15
-rw-r--r--indra/newview/llexperiencelog.h3
-rw-r--r--indra/newview/llface.cpp39
-rw-r--r--indra/newview/llface.h15
-rw-r--r--indra/newview/llfasttimerview.cpp12
-rw-r--r--indra/newview/llfavoritesbar.cpp161
-rw-r--r--indra/newview/llfavoritesbar.h20
-rw-r--r--indra/newview/llfeaturemanager.cpp65
-rw-r--r--indra/newview/llfilepicker.cpp6
-rw-r--r--indra/newview/llfloateraddpaymentmethod.cpp81
-rw-r--r--indra/newview/llfloateraddpaymentmethod.h52
-rw-r--r--indra/newview/llfloaterauction.cpp7
-rw-r--r--indra/newview/llfloateravatarpicker.cpp55
-rw-r--r--indra/newview/llfloateravatartextures.cpp8
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp11
-rw-r--r--indra/newview/llfloaterbulkpermission.h1
-rw-r--r--indra/newview/llfloaterbuy.cpp41
-rw-r--r--indra/newview/llfloaterbuy.h5
-rw-r--r--indra/newview/llfloaterbuycontents.cpp2
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp167
-rw-r--r--indra/newview/llfloaterbuycurrency.h24
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp21
-rw-r--r--indra/newview/llfloatercamera.cpp172
-rw-r--r--indra/newview/llfloatercamera.h21
-rw-r--r--indra/newview/llfloatercamerapresets.cpp145
-rw-r--r--indra/newview/llfloatercamerapresets.h73
-rw-r--r--indra/newview/llfloatercolorpicker.cpp52
-rw-r--r--indra/newview/llfloaterconversationpreview.cpp7
-rw-r--r--indra/newview/llfloaterconversationpreview.h1
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp323
-rw-r--r--indra/newview/llfloatercreatelandmark.h74
-rw-r--r--indra/newview/llfloaterdeleteenvpreset.cpp285
-rw-r--r--indra/newview/llfloaterdeleteprefpreset.cpp32
-rw-r--r--indra/newview/llfloatereditdaycycle.cpp825
-rw-r--r--indra/newview/llfloatereditdaycycle.h137
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp479
-rw-r--r--indra/newview/llfloatereditenvironmentbase.h148
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp1801
-rw-r--r--indra/newview/llfloatereditextdaycycle.h244
-rw-r--r--indra/newview/llfloatereditsky.cpp707
-rw-r--r--indra/newview/llfloatereditsky.h113
-rw-r--r--indra/newview/llfloatereditwater.cpp534
-rw-r--r--indra/newview/llfloatereditwater.h115
-rw-r--r--indra/newview/llfloaterenvironmentadjust.cpp482
-rw-r--r--indra/newview/llfloaterenvironmentadjust.h94
-rw-r--r--indra/newview/llfloaterenvironmentsettings.cpp282
-rw-r--r--indra/newview/llfloaterenvironmentsettings.h71
-rw-r--r--indra/newview/llfloaterevent.cpp2
-rw-r--r--indra/newview/llfloaterexperiencepicker.cpp55
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp554
-rw-r--r--indra/newview/llfloaterfixedenvironment.h138
-rw-r--r--indra/newview/llfloaterforgetuser.cpp348
-rw-r--r--indra/newview/llfloaterforgetuser.h56
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloatergroupinvite.cpp11
-rw-r--r--indra/newview/llfloatergroupinvite.h2
-rw-r--r--indra/newview/llfloatergroups.cpp5
-rw-r--r--indra/newview/llfloaterhandler.cpp9
-rw-r--r--indra/newview/llfloaterhowto.cpp92
-rw-r--r--indra/newview/llfloaterhowto.h58
-rw-r--r--indra/newview/llfloaterimagepreview.cpp15
-rw-r--r--indra/newview/llfloaterimcontainer.cpp171
-rw-r--r--indra/newview/llfloaterimcontainer.h9
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp2
-rw-r--r--indra/newview/llfloaterimsession.cpp1
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp61
-rw-r--r--indra/newview/llfloaterimsessiontab.h4
-rw-r--r--indra/newview/llfloaterjoystick.cpp153
-rw-r--r--indra/newview/llfloaterjoystick.h9
-rw-r--r--indra/newview/llfloaterland.cpp189
-rw-r--r--indra/newview/llfloaterland.h3
-rw-r--r--indra/newview/llfloaterlandholdings.cpp30
-rw-r--r--indra/newview/llfloaterlandholdings.h2
-rw-r--r--indra/newview/llfloaterlinkreplace.cpp85
-rw-r--r--indra/newview/llfloaterlinkreplace.h1
-rw-r--r--indra/newview/llfloaterloadprefpreset.cpp27
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp3
-rw-r--r--indra/newview/llfloatermodelpreview.cpp3833
-rw-r--r--indra/newview/llfloatermodelpreview.h274
-rw-r--r--indra/newview/llfloatermodeluploadbase.h2
-rw-r--r--indra/newview/llfloatermyenvironment.cpp459
-rw-r--r--indra/newview/llfloatermyenvironment.h78
-rw-r--r--indra/newview/llfloaternamedesc.cpp40
-rw-r--r--indra/newview/llfloaternamedesc.h3
-rw-r--r--indra/newview/llfloaterperms.cpp6
-rw-r--r--indra/newview/llfloaterperms.h1
-rw-r--r--indra/newview/llfloaterpreference.cpp1137
-rw-r--r--indra/newview/llfloaterpreference.h83
-rw-r--r--indra/newview/llfloaterpreferenceviewadvanced.cpp82
-rw-r--r--indra/newview/llfloaterpreferenceviewadvanced.h51
-rw-r--r--indra/newview/llfloaterregioninfo.cpp858
-rw-r--r--indra/newview/llfloaterregioninfo.h80
-rw-r--r--indra/newview/llfloaterreporter.cpp15
-rw-r--r--indra/newview/llfloatersavecamerapreset.cpp172
-rw-r--r--indra/newview/llfloatersavecamerapreset.h (renamed from indra/newview/llfloaterdeleteenvpreset.h)44
-rw-r--r--indra/newview/llfloatersaveprefpreset.cpp20
-rw-r--r--indra/newview/llfloatersaveprefpreset.h3
-rw-r--r--indra/newview/llfloatersettingsdebug.cpp42
-rw-r--r--indra/newview/llfloatersidepanelcontainer.cpp14
-rw-r--r--indra/newview/llfloatersidepanelcontainer.h2
-rw-r--r--indra/newview/llfloatersnapshot.h1
-rw-r--r--indra/newview/llfloaterworldmap.h1
-rw-r--r--indra/newview/llflyoutcombobtn.cpp162
-rw-r--r--indra/newview/llflyoutcombobtn.h76
-rw-r--r--indra/newview/llfolderviewmodelinventory.h6
-rw-r--r--indra/newview/llfriendcard.cpp2
-rw-r--r--indra/newview/llgiveinventory.cpp13
-rw-r--r--indra/newview/llglsandbox.cpp59
-rw-r--r--indra/newview/llgroupactions.cpp10
-rw-r--r--indra/newview/llgroupmgr.cpp105
-rw-r--r--indra/newview/llgroupmgr.h6
-rw-r--r--indra/newview/llhudnametag.cpp61
-rw-r--r--indra/newview/llhudnametag.h2
-rw-r--r--indra/newview/llhudobject.h2
-rw-r--r--indra/newview/llhudtext.cpp7
-rw-r--r--indra/newview/llimprocessing.cpp125
-rw-r--r--indra/newview/llimview.cpp83
-rw-r--r--indra/newview/llimview.h1
-rw-r--r--indra/newview/llinventorybridge.cpp298
-rw-r--r--indra/newview/llinventorybridge.h30
-rw-r--r--indra/newview/llinventoryfilter.cpp274
-rw-r--r--indra/newview/llinventoryfilter.h43
-rw-r--r--indra/newview/llinventoryfunctions.cpp162
-rw-r--r--indra/newview/llinventoryfunctions.h6
-rw-r--r--indra/newview/llinventoryicon.cpp15
-rw-r--r--indra/newview/llinventoryicon.h1
-rw-r--r--indra/newview/llinventorymodel.cpp223
-rw-r--r--indra/newview/llinventorypanel.cpp589
-rw-r--r--indra/newview/llinventorypanel.h99
-rw-r--r--indra/newview/lljoystickbutton.cpp332
-rw-r--r--indra/newview/lljoystickbutton.h53
-rw-r--r--indra/newview/llkeyconflict.cpp1015
-rw-r--r--indra/newview/llkeyconflict.h175
-rw-r--r--indra/newview/lllandmarkactions.cpp24
-rw-r--r--indra/newview/lllandmarkactions.h6
-rw-r--r--indra/newview/lllandmarklist.cpp53
-rw-r--r--indra/newview/lllandmarklist.h7
-rw-r--r--indra/newview/lllegacyatmospherics.cpp853
-rw-r--r--indra/newview/lllegacyatmospherics.h284
-rw-r--r--indra/newview/lllocalbitmaps.cpp13
-rw-r--r--indra/newview/lllocalbitmaps.h1
-rw-r--r--indra/newview/lllocationinputctrl.cpp16
-rw-r--r--indra/newview/lllocationinputctrl.h1
-rw-r--r--indra/newview/lllogchat.cpp89
-rw-r--r--indra/newview/lllogchat.h4
-rw-r--r--indra/newview/llloginhandler.cpp7
-rw-r--r--indra/newview/lllogininstance.cpp39
-rw-r--r--indra/newview/llmachineid.cpp2
-rw-r--r--indra/newview/llmaniprotate.cpp23
-rw-r--r--indra/newview/llmaniprotate.h1
-rw-r--r--indra/newview/llmarketplacefunctions.cpp5
-rw-r--r--indra/newview/llmarketplacefunctions.h4
-rw-r--r--indra/newview/llmediactrl.cpp19
-rw-r--r--indra/newview/llmediactrl.h1
-rw-r--r--indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp1
-rw-r--r--indra/newview/llmeshrepository.cpp228
-rw-r--r--indra/newview/llmeshrepository.h11
-rw-r--r--indra/newview/llmodelpreview.cpp3570
-rw-r--r--indra/newview/llmodelpreview.h313
-rw-r--r--indra/newview/llmoveview.cpp2
-rw-r--r--indra/newview/llmutelist.cpp97
-rw-r--r--indra/newview/llmutelist.h6
-rw-r--r--indra/newview/llnavigationbar.cpp10
-rwxr-xr-xindra/newview/llnavigationbar.h2
-rw-r--r--indra/newview/llnetmap.cpp2
-rw-r--r--indra/newview/llnotificationhandler.h1
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp15
-rw-r--r--indra/newview/llnotificationofferhandler.cpp16
-rw-r--r--indra/newview/lloutfitgallery.cpp10
-rw-r--r--indra/newview/lloutfitslist.cpp2
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp14
-rw-r--r--indra/newview/lloutputmonitorctrl.h3
-rw-r--r--indra/newview/llpanelavatar.cpp1
-rw-r--r--indra/newview/llpanelclassified.cpp1
-rw-r--r--indra/newview/llpanelcontents.cpp1
-rw-r--r--indra/newview/llpaneleditsky.cpp976
-rw-r--r--indra/newview/llpaneleditsky.h173
-rw-r--r--indra/newview/llpaneleditwater.cpp251
-rw-r--r--indra/newview/llpaneleditwater.h98
-rw-r--r--indra/newview/llpaneleditwearable.cpp6
-rw-r--r--indra/newview/llpanelenvironment.cpp1178
-rw-r--r--indra/newview/llpanelenvironment.h222
-rw-r--r--indra/newview/llpanelexperiences.cpp13
-rw-r--r--indra/newview/llpanelexperiences.h2
-rw-r--r--indra/newview/llpanelface.cpp34
-rw-r--r--indra/newview/llpanelgroup.cpp41
-rw-r--r--indra/newview/llpanelgroup.h3
-rw-r--r--indra/newview/llpanelgroupcreate.cpp237
-rw-r--r--indra/newview/llpanelgroupcreate.h73
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp58
-rw-r--r--indra/newview/llpanelgroupgeneral.h1
-rw-r--r--indra/newview/llpanelgroupnotices.cpp10
-rw-r--r--indra/newview/llpanelgrouproles.cpp2
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp98
-rw-r--r--indra/newview/llpanellandmarkinfo.h34
-rw-r--r--indra/newview/llpanellandmarks.cpp733
-rw-r--r--indra/newview/llpanellandmarks.h105
-rw-r--r--indra/newview/llpanellogin.cpp554
-rw-r--r--indra/newview/llpanellogin.h18
-rw-r--r--indra/newview/llpanelmaininventory.cpp115
-rw-r--r--indra/newview/llpanelmaininventory.h6
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.cpp74
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.h19
-rw-r--r--indra/newview/llpanelnearbymedia.cpp81
-rw-r--r--indra/newview/llpanelnearbymedia.h9
-rw-r--r--indra/newview/llpanelobject.cpp1
-rw-r--r--indra/newview/llpanelobjectinventory.cpp44
-rw-r--r--indra/newview/llpaneloutfitedit.cpp26
-rw-r--r--indra/newview/llpaneloutfitedit.h3
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp31
-rw-r--r--indra/newview/llpaneloutfitsinventory.h5
-rw-r--r--indra/newview/llpanelpeople.cpp60
-rw-r--r--indra/newview/llpanelpermissions.cpp38
-rw-r--r--indra/newview/llpanelpicks.cpp11
-rw-r--r--indra/newview/llpanelplaceinfo.cpp65
-rw-r--r--indra/newview/llpanelplaceinfo.h2
-rw-r--r--indra/newview/llpanelplaceprofile.cpp8
-rw-r--r--indra/newview/llpanelplaceprofile.h2
-rw-r--r--indra/newview/llpanelplaces.cpp235
-rw-r--r--indra/newview/llpanelplaces.h18
-rw-r--r--indra/newview/llpanelplacestab.cpp8
-rw-r--r--indra/newview/llpanelplacestab.h20
-rw-r--r--indra/newview/llpanelpresetscamerapulldown.cpp149
-rw-r--r--indra/newview/llpanelpresetscamerapulldown.h49
-rw-r--r--indra/newview/llpanelpresetspulldown.cpp83
-rw-r--r--indra/newview/llpanelpresetspulldown.h16
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp73
-rw-r--r--indra/newview/llpanelprimmediacontrols.h8
-rw-r--r--indra/newview/llpanelpulldown.cpp118
-rw-r--r--indra/newview/llpanelpulldown.h55
-rw-r--r--indra/newview/llpanelsnapshot.cpp3
-rw-r--r--indra/newview/llpanelsnapshotinventory.cpp8
-rw-r--r--indra/newview/llpanelsnapshotoptions.cpp11
-rw-r--r--indra/newview/llpanelsnapshotpostcard.cpp6
-rw-r--r--indra/newview/llpanelteleporthistory.cpp359
-rw-r--r--indra/newview/llpanelteleporthistory.h54
-rw-r--r--indra/newview/llpaneltopinfobar.cpp3
-rw-r--r--indra/newview/llpanelvolume.cpp31
-rw-r--r--indra/newview/llpanelvolumepulldown.cpp60
-rw-r--r--indra/newview/llpanelvolumepulldown.h15
-rw-r--r--indra/newview/llpanelwearing.cpp48
-rw-r--r--indra/newview/llparticipantlist.cpp7
-rw-r--r--indra/newview/llplacesinventorypanel.cpp4
-rw-r--r--indra/newview/llplacesinventorypanel.h8
-rw-r--r--indra/newview/llpresetsmanager.cpp486
-rw-r--r--indra/newview/llpresetsmanager.h38
-rw-r--r--indra/newview/llpreviewgesture.cpp29
-rw-r--r--indra/newview/llpreviewgesture.h2
-rw-r--r--indra/newview/llpreviewnotecard.cpp20
-rw-r--r--indra/newview/llpreviewscript.cpp28
-rw-r--r--indra/newview/llpreviewscript.h1
-rw-r--r--indra/newview/llpreviewtexture.cpp2
-rw-r--r--indra/newview/llprogressview.cpp226
-rw-r--r--indra/newview/llprogressview.h25
-rw-r--r--indra/newview/llrecentpeople.h2
-rw-r--r--indra/newview/llremoteparcelrequest.h2
-rw-r--r--indra/newview/llscenemonitor.cpp229
-rw-r--r--indra/newview/llscriptruntimeperms.h8
-rw-r--r--indra/newview/llsearchableui.cpp14
-rw-r--r--indra/newview/llsearchableui.h1
-rw-r--r--indra/newview/llsecapi.cpp11
-rw-r--r--indra/newview/llsecapi.h67
-rw-r--r--indra/newview/llsechandler_basic.cpp207
-rw-r--r--indra/newview/llsechandler_basic.h65
-rw-r--r--indra/newview/llselectmgr.cpp108
-rw-r--r--indra/newview/llselectmgr.h9
-rw-r--r--indra/newview/llsetkeybinddialog.cpp380
-rw-r--r--indra/newview/llsetkeybinddialog.h106
-rw-r--r--indra/newview/llsettingspicker.cpp509
-rw-r--r--indra/newview/llsettingspicker.h137
-rw-r--r--indra/newview/llsettingsvo.cpp1462
-rw-r--r--indra/newview/llsettingsvo.h192
-rw-r--r--indra/newview/llsidepanelappearance.cpp62
-rw-r--r--indra/newview/llsidepanelappearance.h5
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp24
-rw-r--r--indra/newview/llskinningutil.cpp47
-rw-r--r--indra/newview/llskinningutil.h28
-rw-r--r--indra/newview/llsky.cpp249
-rw-r--r--indra/newview/llsky.h56
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp82
-rw-r--r--indra/newview/llspatialpartition.cpp152
-rw-r--r--indra/newview/llspatialpartition.h24
-rw-r--r--indra/newview/llstartup.cpp458
-rw-r--r--indra/newview/llstartup.h6
-rw-r--r--indra/newview/llstartuplistener.cpp26
-rw-r--r--indra/newview/llstartuplistener.h1
-rw-r--r--indra/newview/llstatusbar.cpp59
-rw-r--r--indra/newview/llstatusbar.h6
-rw-r--r--indra/newview/lltelemetry.cpp145
-rw-r--r--indra/newview/lltelemetry.h81
-rw-r--r--indra/newview/llteleporthistorystorage.cpp22
-rw-r--r--indra/newview/llteleporthistorystorage.h7
-rw-r--r--indra/newview/lltexturecache.cpp100
-rw-r--r--indra/newview/lltexturecache.h10
-rw-r--r--indra/newview/lltexturectrl.cpp122
-rw-r--r--indra/newview/lltexturectrl.h6
-rw-r--r--indra/newview/lltexturefetch.cpp5
-rw-r--r--indra/newview/lltexturefetch.h1
-rw-r--r--indra/newview/lltexturestats.cpp4
-rw-r--r--indra/newview/lltextureview.cpp6
-rw-r--r--indra/newview/lltoast.cpp23
-rw-r--r--indra/newview/lltoastalertpanel.cpp113
-rw-r--r--indra/newview/lltoastalertpanel.h10
-rw-r--r--indra/newview/lltoastnotifypanel.cpp29
-rw-r--r--indra/newview/lltoastnotifypanel.h2
-rw-r--r--indra/newview/lltoastpanel.cpp108
-rw-r--r--indra/newview/lltoastpanel.h19
-rw-r--r--indra/newview/lltool.cpp14
-rw-r--r--indra/newview/lltool.h3
-rw-r--r--indra/newview/lltooldraganddrop.cpp6
-rw-r--r--indra/newview/lltoolgrab.cpp5
-rw-r--r--indra/newview/lltoolgrab.h1
-rw-r--r--indra/newview/lltoolgun.cpp11
-rw-r--r--indra/newview/lltoolmgr.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp289
-rw-r--r--indra/newview/lltoolpie.h9
-rw-r--r--indra/newview/lltracker.cpp4
-rw-r--r--indra/newview/lltrackpicker.cpp134
-rw-r--r--indra/newview/lltrackpicker.h58
-rw-r--r--indra/newview/lltranslate.cpp20
-rw-r--r--indra/newview/lluploadfloaterobservers.h2
-rw-r--r--indra/newview/llurlfloaterdispatchhandler.cpp214
-rw-r--r--indra/newview/llurlfloaterdispatchhandler.h49
-rw-r--r--indra/newview/llversioninfo.cpp107
-rw-r--r--indra/newview/llversioninfo.h68
-rw-r--r--indra/newview/llviewerassetstorage.cpp90
-rw-r--r--indra/newview/llviewerassetstorage.h54
-rw-r--r--indra/newview/llviewerassettype.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp93
-rw-r--r--indra/newview/llviewerassetupload.h10
-rw-r--r--indra/newview/llviewercamera.cpp25
-rw-r--r--indra/newview/llviewercamera.h8
-rw-r--r--indra/newview/llviewercontrol.cpp34
-rw-r--r--indra/newview/llviewercontrollistener.cpp12
-rw-r--r--indra/newview/llviewerdisplay.cpp195
-rw-r--r--indra/newview/llviewerdisplay.h1
-rw-r--r--indra/newview/llviewerfloaterreg.cpp37
-rw-r--r--indra/newview/llviewerfoldertype.cpp3
-rw-r--r--indra/newview/llviewergenericmessage.cpp24
-rw-r--r--indra/newview/llviewergenericmessage.h1
-rw-r--r--indra/newview/llviewerinput.cpp1540
-rw-r--r--indra/newview/llviewerinput.h179
-rw-r--r--indra/newview/llviewerinventory.cpp210
-rw-r--r--indra/newview/llviewerinventory.h38
-rw-r--r--indra/newview/llviewerjoint.cpp7
-rw-r--r--indra/newview/llviewerjointmesh.cpp30
-rw-r--r--indra/newview/llviewerjoystick.cpp420
-rw-r--r--indra/newview/llviewerjoystick.h10
-rw-r--r--indra/newview/llviewerkeyboard.cpp1032
-rw-r--r--indra/newview/llviewerkeyboard.h118
-rw-r--r--indra/newview/llviewermedia.cpp53
-rw-r--r--indra/newview/llviewermedia.h4
-rw-r--r--indra/newview/llviewermediafocus.cpp39
-rw-r--r--indra/newview/llviewermediafocus.h8
-rw-r--r--indra/newview/llviewermenu.cpp507
-rw-r--r--indra/newview/llviewermenu.h9
-rw-r--r--indra/newview/llviewermenufile.cpp156
-rw-r--r--indra/newview/llviewermenufile.h2
-rw-r--r--indra/newview/llviewermessage.cpp143
-rw-r--r--indra/newview/llviewernetwork.cpp2
-rw-r--r--indra/newview/llviewerobject.cpp36
-rw-r--r--indra/newview/llviewerobject.h5
-rw-r--r--indra/newview/llvieweroctree.cpp6
-rw-r--r--indra/newview/llviewerparcelaskplay.cpp306
-rw-r--r--indra/newview/llviewerparcelaskplay.h89
-rw-r--r--indra/newview/llviewerparcelmedia.cpp31
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.cpp53
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.h4
-rw-r--r--indra/newview/llviewerparcelmgr.cpp144
-rw-r--r--indra/newview/llviewerparcelmgr.h6
-rw-r--r--indra/newview/llviewerpartsource.cpp2
-rw-r--r--indra/newview/llviewerprecompiledheaders.h2
-rw-r--r--indra/newview/llviewerregion.cpp75
-rw-r--r--indra/newview/llviewerregion.h16
-rw-r--r--indra/newview/llviewershadermgr.cpp2195
-rw-r--r--indra/newview/llviewershadermgr.h29
-rw-r--r--indra/newview/llviewerstats.cpp97
-rw-r--r--indra/newview/llviewerstats.h2
-rw-r--r--indra/newview/llviewertexlayer.cpp2
-rw-r--r--indra/newview/llviewertexlayer.h2
-rw-r--r--indra/newview/llviewertexteditor.cpp105
-rw-r--r--indra/newview/llviewertexteditor.h1
-rw-r--r--indra/newview/llviewertexture.cpp45
-rw-r--r--indra/newview/llviewertexture.h8
-rw-r--r--indra/newview/llviewertexturelist.cpp7
-rw-r--r--indra/newview/llviewerwearable.cpp17
-rw-r--r--indra/newview/llviewerwindow.cpp502
-rw-r--r--indra/newview/llviewerwindow.h14
-rw-r--r--indra/newview/llviewerwindowlistener.cpp8
-rw-r--r--indra/newview/llvoavatar.cpp1237
-rw-r--r--indra/newview/llvoavatar.h76
-rw-r--r--indra/newview/llvoavatarself.cpp95
-rw-r--r--indra/newview/llvoavatarself.h2
-rw-r--r--indra/newview/llvocache.cpp51
-rw-r--r--indra/newview/llvograss.cpp22
-rw-r--r--indra/newview/llvoground.cpp2
-rw-r--r--indra/newview/llvoiceclient.cpp79
-rw-r--r--indra/newview/llvoiceclient.h16
-rw-r--r--indra/newview/llvoicevivox.cpp345
-rw-r--r--indra/newview/llvoicevivox.h8
-rw-r--r--indra/newview/llvosky.cpp1904
-rw-r--r--indra/newview/llvosky.h526
-rw-r--r--indra/newview/llvotree.cpp63
-rw-r--r--indra/newview/llvotree.h4
-rw-r--r--indra/newview/llvovolume.cpp234
-rw-r--r--indra/newview/llvovolume.h27
-rw-r--r--indra/newview/llvowater.cpp2
-rw-r--r--indra/newview/llvowlsky.cpp432
-rw-r--r--indra/newview/llvowlsky.h22
-rw-r--r--indra/newview/llwatchdog.cpp6
-rw-r--r--indra/newview/llwaterparammanager.cpp442
-rw-r--r--indra/newview/llwaterparammanager.h413
-rw-r--r--indra/newview/llwaterparamset.cpp266
-rw-r--r--indra/newview/llwaterparamset.h165
-rw-r--r--indra/newview/llwearableitemslist.cpp76
-rw-r--r--indra/newview/llwearableitemslist.h7
-rw-r--r--indra/newview/llweb.cpp12
-rw-r--r--indra/newview/llwindebug.h4
-rw-r--r--indra/newview/llwindowlistener.cpp6
-rw-r--r--indra/newview/llwlanimator.cpp324
-rw-r--r--indra/newview/llwlanimator.h139
-rw-r--r--indra/newview/llwldaycycle.cpp114
-rw-r--r--indra/newview/llwldaycycle.h8
-rw-r--r--indra/newview/llwlhandlers.cpp45
-rw-r--r--indra/newview/llwlhandlers.h15
-rw-r--r--indra/newview/llwlparammanager.cpp710
-rw-r--r--indra/newview/llwlparammanager.h323
-rw-r--r--indra/newview/llwlparamset.cpp423
-rw-r--r--indra/newview/llwlparamset.h246
-rw-r--r--indra/newview/llworld.cpp71
-rw-r--r--indra/newview/llworld.h3
-rw-r--r--indra/newview/llworldmapview.cpp2
-rw-r--r--indra/newview/llworldmipmap.cpp2
-rw-r--r--indra/newview/llxmlrpclistener.cpp48
-rw-r--r--indra/newview/llxmlrpctransaction.cpp10
-rw-r--r--indra/newview/pipeline.cpp4288
-rw-r--r--indra/newview/pipeline.h86
-rwxr-xr-xindra/newview/res/viewerRes.rc2
-rw-r--r--indra/newview/roles_constants.h3
-rw-r--r--indra/newview/skins/default/colors.xml12
-rw-r--r--indra/newview/skins/default/textures/3p_icons/fmod_logo.pngbin0 -> 14486 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/havok_logo.pngbin0 -> 41488 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/vivox_logo.pngbin0 -> 2331 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.pngbin0 -> 10689 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.pngbin0 -> 1714 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/TabTop_Right_Flashing.pngbin0 -> 252 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Settings.pngbin0 -> 925 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_SettingsDay.pngbin0 -> 925 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_SettingsSky.pngbin0 -> 883 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_SettingsWater.pngbin0 -> 764 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.pngbin0 -> 756 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Presets_Icon.pngbin366 -> 1293 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Presets_Icon_Graphic.pngbin0 -> 366 bytes
-rw-r--r--indra/newview/skins/default/textures/navbar/Landmarks.pngbin0 -> 15870 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml44
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/environments.pngbin0 -> 1630 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ProgressBarSolid.pngbin0 -> 208 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.pngbin475 -> 429 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.pngbin0 -> 16287 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_moon_back.pngbin0 -> 913 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_moon_front.pngbin0 -> 1156 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_bottom.pngbin0 -> 874 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_bottom_active.pngbin0 -> 362 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_left_side.pngbin0 -> 870 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_left_side_active.pngbin0 -> 340 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_right_side.pngbin0 -> 879 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_right_side_active.pngbin0 -> 358 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_top.pngbin0 -> 883 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_rotate_top_active.pngbin0 -> 367 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_sphere.pngbin0 -> 6863 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_sun_back.pngbin0 -> 856 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/track_control_sun_front.pngbin0 -> 1053 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Icon_Gear.pngbin0 -> 6229 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/add_payment_image_center.pngbin0 -> 31996 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/add_payment_image_left.pngbin0 -> 30102 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/add_payment_image_right.pngbin0 -> 29761 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_left.pngbin384997 -> 271413 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/first_login_image_right.pngbin340188 -> 366068 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/login_sl_logo.pngbin21797 -> 5764 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/login_sl_logo_small.pngbin5978 -> 4802 bytes
-rw-r--r--indra/newview/skins/default/xui/da/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/da/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/da/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/da/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/da/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/da/menu_wearing_tab.xml4
-rw-r--r--indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml1
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/de/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/de/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/de/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/de/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/de/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/de/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/de/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/de/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/de/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_texture.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/de/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/de/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/de/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/de/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/de/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/de/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/de/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/de/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/de/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/de/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/de/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml125
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/de/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/de/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/de/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/de/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/de/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/de/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml115
-rw-r--r--indra/newview/skins/default/xui/en/control_table_contents_camera.xml240
-rw-r--r--indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml19
-rw-r--r--indra/newview/skins/default/xui/en/control_table_contents_editing.xml80
-rw-r--r--indra/newview/skins/default/xui/en/control_table_contents_media.xml76
-rw-r--r--indra/newview/skins/default/xui/en/control_table_contents_movement.xml198
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml18
-rw-r--r--indra/newview/skins/default/xui/en/floater_add_payment_method.xml140
-rw-r--r--indra/newview/skins/default/xui/en/floater_adjust_environment.xml477
-rw-r--r--indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml15
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_textures.xml137
-rw-r--r--indra/newview/skins/default/xui/en/floater_beacons.xml41
-rw-r--r--indra/newview/skins/default/xui/en/floater_bulk_perms.xml15
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_currency.xml666
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_object.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera.xml287
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera_presets.xml23
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml113
-rw-r--r--indra/newview/skins/default/xui/en/floater_delete_env_preset.xml59
-rw-r--r--indra/newview/skins/default/xui/en/floater_delete_pref_preset.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml485
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml651
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_hover_height.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml953
-rw-r--r--indra/newview/skins/default/xui/en/floater_edit_water_preset.xml448
-rw-r--r--indra/newview/skins/default/xui/en/floater_environment_settings.xml162
-rw-r--r--indra/newview/skins/default/xui/en/floater_fixedenvironment.xml161
-rw-r--r--indra/newview/skins/default/xui/en/floater_forget_user.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_how_to.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml32
-rw-r--r--indra/newview/skins/default/xui/en/floater_image_preview.xml17
-rw-r--r--indra/newview/skins/default/xui/en/floater_inspect.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml29
-rw-r--r--indra/newview/skins/default/xui/en/floater_joystick.xml165
-rw-r--r--indra/newview/skins/default/xui/en/floater_load_pref_preset.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_merchant_outbox.xml156
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml591
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_appearance.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_environments.xml200
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_scripts.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_people.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml61
-rw-r--r--indra/newview/skins/default/xui/en/floater_pick_track.xml129
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml45
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_view_advanced.xml156
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_trash.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_publish_classified.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_save_camera_preset.xml70
-rw-r--r--indra/newview/skins/default/xui/en/floater_save_pref_preset.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_script_debug.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_select_key.xml63
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml152
-rw-r--r--indra/newview/skins/default/xui/en/floater_sound_preview.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml404
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml68
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_other.xml5
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml343
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_other.xml5
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_self.xml477
-rw-r--r--indra/newview/skins/default/xui/en/menu_cof_attachment.xml20
-rw-r--r--indra/newview/skins/default/xui/en/menu_favorites.xml37
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml78
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml39
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml44
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_picks.xml26
-rw-r--r--indra/newview/skins/default/xui/en/menu_place_add_button.xml23
-rw-r--r--indra/newview/skins/default/xui/en/menu_places_gear_folder.xml43
-rw-r--r--indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml122
-rw-r--r--indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml46
-rw-r--r--indra/newview/skins/default/xui/en/menu_save_settings.xml68
-rw-r--r--indra/newview/skins/default/xui/en/menu_script_chiclet.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_settings_add.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_settings_gear.xml86
-rw-r--r--indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml13
-rw-r--r--indra/newview/skins/default/xui/en/menu_teleport_history_item.xml46
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml755
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearable_list_item.xml31
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearing_gear.xml27
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearing_tab.xml25
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml584
-rw-r--r--indra/newview/skins/default/xui/en/panel_camera_preset_item.xml76
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_wearable.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_favorites.xml22
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml314
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml105
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmarks.xml199
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml60
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml29
-rw-r--r--indra/newview/skins/default/xui/en/panel_outbox_inventory.xml31
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml1053
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml21
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml61
-rw-r--r--indra/newview/skins/default/xui/en/panel_places.xml327
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml23
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_controls.xml63
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml20
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml90
-rw-r--r--indra/newview/skins/default/xui/en/panel_presets_camera_pulldown.xml69
-rw-r--r--indra/newview/skins/default/xui/en/panel_progress.xml159
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_environment.xml1044
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml322
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml271
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_density.xml273
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml411
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_water.xml374
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_options.xml14
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml14
-rw-r--r--indra/newview/skins/default/xui/en/panel_teleport_history.xml35
-rw-r--r--indra/newview/skins/default/xui/en/role_actions.xml5
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml6
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml103
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml3
-rw-r--r--indra/newview/skins/default/xui/en/widgets/density_ctrl.xml164
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/joystick_quat.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/line_editor.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_editor.xml4
-rw-r--r--indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml68
-rw-r--r--indra/newview/skins/default/xui/en/widgets/xy_vector.xml29
-rw-r--r--indra/newview/skins/default/xui/es/floater_about_land.xml5
-rw-r--r--indra/newview/skins/default/xui/es/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/es/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/es/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/es/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/es/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/es/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/es/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/es/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/es/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_texture.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/es/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/es/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/es/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/es/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/es/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/es/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/es/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/es/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/es/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/es/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/es/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/es/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml125
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_estate.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/es/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/es/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/es/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/es/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/es/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml106
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about_land.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/fr/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/fr/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/fr/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/fr/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_texture.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/fr/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml125
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/fr/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/fr/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/fr/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml115
-rw-r--r--indra/newview/skins/default/xui/it/floater_about_land.xml9
-rw-r--r--indra/newview/skins/default/xui/it/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/it/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/it/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/it/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/it/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/it/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/it/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/it/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/it/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_texture.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/it/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/it/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/it/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/it/menu_inventory_add.xml10
-rw-r--r--indra/newview/skins/default/xui/it/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/it/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/it/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/it/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/it/menu_viewer.xml31
-rw-r--r--indra/newview/skins/default/xui/it/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/it/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/it/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml123
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/it/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/it/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/it/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/it/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/it/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/it/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml115
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about_land.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/ja/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/ja/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/ja/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/ja/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml123
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/ja/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/ja/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml115
-rw-r--r--indra/newview/skins/default/xui/pl/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml29
-rw-r--r--indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml11
-rw-r--r--indra/newview/skins/default/xui/pl/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/pl/menu_viewer.xml5
-rw-r--r--indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/pl/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/menu_wearing_tab.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml1
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about_land.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/pt/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/pt/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/pt/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/pt/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/pt/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/pt/menu_inventory_add.xml10
-rw-r--r--indra/newview/skins/default/xui/pt/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/pt/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml125
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/pt/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/pt/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/pt/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/pt/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml109
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about_land.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/ru/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/ru/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/ru/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/ru/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preview_texture.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/ru/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/ru/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/ru/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml133
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_chat.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/ru/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/ru/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/ru/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/ru/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/ru/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml115
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about_land.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/tr/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/tr/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/tr/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/tr/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/tr/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preview_texture.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/tr/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/tr/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/tr/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml124
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_me.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_people.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/tr/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/tr/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/tr/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/tr/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/tr/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml109
-rw-r--r--indra/newview/skins/default/xui/zh/floater_about_land.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/floater_adjust_environment.xml24
-rw-r--r--indra/newview/skins/default/xui/zh/floater_beacons.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_bulk_perms.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/floater_buy_currency.xml5
-rw-r--r--indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/floater_edit_ext_day_cycle.xml107
-rw-r--r--indra/newview/skins/default/xui/zh/floater_fixedenvironment.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/floater_my_environments.xml24
-rw-r--r--indra/newview/skins/default/xui/zh/floater_perms_default.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pick_track.xml22
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_settings_picker.xml30
-rw-r--r--indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/menu_cof_attachment.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inventory_add.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_outfit_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/menu_save_settings.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_settings_add.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/menu_settings_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/menu_viewer.xml29
-rw-r--r--indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/menu_wearing_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_wearing_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml87
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_universal.xml19
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_wearable.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_environment.xml143
-rw-r--r--indra/newview/skins/default/xui/zh/panel_settings_sky_atmos.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_settings_sky_clouds.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_settings_sky_density.xml27
-rw-r--r--indra/newview/skins/default/xui/zh/panel_settings_sky_sunmoon.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/panel_settings_water.xml19
-rw-r--r--indra/newview/skins/default/xui/zh/panel_tools_texture.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/role_actions.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml99
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp8
-rw-r--r--indra/newview/tests/llsecapi_test.cpp10
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp8
-rw-r--r--indra/newview/tests/llversioninfo_test.cpp24
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp4
-rwxr-xr-xindra/newview/viewer_manifest.py208
1392 files changed, 77757 insertions, 38761 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 04f6c9b7f0..424fd17707 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -15,10 +15,9 @@ include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
include(DBusGlib)
-include(DirectX)
include(DragDrop)
include(EXPAT)
-include(FMODEX)
+include(FMODSTUDIO)
include(GLOD)
include(Hunspell)
include(JsonCpp)
@@ -63,9 +62,9 @@ if (NOT HAVOK_TPV)
add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
endif (NOT HAVOK_TPV)
-if(FMODEX)
- include_directories(${FMODEX_INCLUDE_DIR})
-endif(FMODEX)
+if(FMODSTUDIO)
+ include_directories(${FMODSTUDIO_INCLUDE_DIR})
+endif(FMODSTUDIO)
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
@@ -115,6 +114,7 @@ set(viewer_SOURCE_FILES
llaisapi.cpp
llagent.cpp
llagentaccess.cpp
+ llagentbenefits.cpp
llagentcamera.cpp
llagentdata.cpp
llagentlanguage.cpp
@@ -170,7 +170,6 @@ set(viewer_SOURCE_FILES
llcurrencyuimanager.cpp
llcylinder.cpp
lldateutil.cpp
- lldaycyclemanager.cpp
lldebugmessagebox.cpp
lldebugview.cpp
lldeferredsounds.cpp
@@ -193,7 +192,7 @@ set(viewer_SOURCE_FILES
lldrawpoolwlsky.cpp
lldynamictexture.cpp
llemote.cpp
- llenvmanager.cpp
+ llenvironment.cpp
llestateinfomodel.cpp
lleventnotifier.cpp
lleventpoll.cpp
@@ -210,6 +209,7 @@ set(viewer_SOURCE_FILES
llflexibleobject.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
+ llfloateraddpaymentmethod.cpp
llfloaterauction.cpp
llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
@@ -228,22 +228,24 @@ set(viewer_SOURCE_FILES
llfloaterbuycurrencyhtml.cpp
llfloaterbuyland.cpp
llfloatercamera.cpp
+ llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
- llfloaterdeleteenvpreset.cpp
+ llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
- llfloatereditdaycycle.cpp
- llfloatereditsky.cpp
- llfloatereditwater.cpp
- llfloaterenvironmentsettings.cpp
+ llfloatereditenvironmentbase.cpp
+ llfloatereditextdaycycle.cpp
+ llfloaterenvironmentadjust.cpp
llfloaterevent.cpp
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
+ llfloaterfixedenvironment.cpp
llfloaterfonttest.cpp
+ llfloaterforgetuser.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
llfloatergotoline.cpp
@@ -254,6 +256,7 @@ set(viewer_SOURCE_FILES
llfloaterhandler.cpp
llfloaterhelpbrowser.cpp
llfloaterhoverheight.cpp
+ llfloaterhowto.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterimsessiontab.cpp
@@ -273,6 +276,7 @@ set(viewer_SOURCE_FILES
llfloatermodelpreview.cpp
llfloatermodeluploadbase.cpp
llfloatermyscripts.cpp
+ llfloatermyenvironment.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
@@ -288,12 +292,14 @@ set(viewer_SOURCE_FILES
llfloaterperms.cpp
llfloaterpostprocess.cpp
llfloaterpreference.cpp
+ llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
llfloaterreporter.cpp
llfloaterregionrestarting.cpp
+ llfloatersavecamerapreset.cpp
llfloatersaveprefpreset.cpp
llfloatersceneloadstats.cpp
llfloaterscriptdebug.cpp
@@ -327,6 +333,7 @@ set(viewer_SOURCE_FILES
llfolderviewmodelinventory.cpp
llfollowcam.cpp
llfriendcard.cpp
+ llflyoutcombobtn.cpp
llgesturelistener.cpp
llgesturemgr.cpp
llgiveinventory.cpp
@@ -372,8 +379,10 @@ set(viewer_SOURCE_FILES
llinventoryobserver.cpp
llinventorypanel.cpp
lljoystickbutton.cpp
+ llkeyconflict.cpp
lllandmarkactions.cpp
lllandmarklist.cpp
+ lllegacyatmospherics.cpp
lllistbrowser.cpp
lllistcontextmenu.cpp
lllistview.cpp
@@ -397,6 +406,7 @@ set(viewer_SOURCE_FILES
llmenuoptionpathfindingrebakenavmesh.cpp
llmeshrepository.cpp
llmimetypes.cpp
+ llmodelpreview.cpp
llmorphview.cpp
llmoveview.cpp
llmutelist.cpp
@@ -429,7 +439,10 @@ set(viewer_SOURCE_FILES
llpanelblockedlist.cpp
llpanelclassified.cpp
llpanelcontents.cpp
+ llpaneleditsky.cpp
+ llpaneleditwater.cpp
llpaneleditwearable.cpp
+ llpanelenvironment.cpp
llpanelexperiencelisteditor.cpp
llpanelexperiencelog.cpp
llpanelexperiencepicker.cpp
@@ -437,6 +450,7 @@ set(viewer_SOURCE_FILES
llpanelface.cpp
llpanelgenerictip.cpp
llpanelgroup.cpp
+ llpanelgroupcreate.cpp
llpanelgroupbulk.cpp
llpanelgroupbulkban.cpp
llpanelgroupexperiences.cpp
@@ -475,6 +489,7 @@ set(viewer_SOURCE_FILES
llpanelplaceprofile.cpp
llpanelplaces.cpp
llpanelplacestab.cpp
+ llpanelpresetscamerapulldown.cpp
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
@@ -488,6 +503,7 @@ set(viewer_SOURCE_FILES
llpaneltiptoast.cpp
llpanelvoiceeffect.cpp
llpaneltopinfobar.cpp
+ llpanelpulldown.cpp
llpanelvoicedevicesettings.cpp
llpanelvolume.cpp
llpanelvolumepulldown.cpp
@@ -545,6 +561,9 @@ set(viewer_SOURCE_FILES
llsecapi.cpp
llsechandler_basic.cpp
llselectmgr.cpp
+ llsetkeybinddialog.cpp
+ llsettingspicker.cpp
+ llsettingsvo.cpp
llshareavatarhandler.cpp
llsidepanelappearance.cpp
llsidepanelinventory.cpp
@@ -570,6 +589,7 @@ set(viewer_SOURCE_FILES
llsyntaxid.cpp
llsyswellitem.cpp
llsyswellwindow.cpp
+ lltelemetry.cpp
llteleporthistory.cpp
llteleporthistorystorage.cpp
lltextureatlas.cpp
@@ -609,6 +629,7 @@ set(viewer_SOURCE_FILES
lltoolselectland.cpp
lltoolselectrect.cpp
lltracker.cpp
+ lltrackpicker.cpp
lltransientdockablefloater.cpp
lltransientfloatermgr.cpp
lltranslate.cpp
@@ -618,6 +639,7 @@ set(viewer_SOURCE_FILES
llurl.cpp
llurldispatcher.cpp
llurldispatcherlistener.cpp
+ llurlfloaterdispatchhandler.cpp
llurlhistory.cpp
llurllineeditorctrl.cpp
llurlwhitelist.cpp
@@ -647,7 +669,7 @@ set(viewer_SOURCE_FILES
llviewerjointattachment.cpp
llviewerjointmesh.cpp
llviewerjoystick.cpp
- llviewerkeyboard.cpp
+ llviewerinput.cpp
llviewerlayer.cpp
llviewermedia.cpp
llviewermedia_streamingaudio.cpp
@@ -659,6 +681,7 @@ set(viewer_SOURCE_FILES
llviewerobject.cpp
llviewerobjectlist.cpp
llvieweroctree.cpp
+ llviewerparcelaskplay.cpp
llviewerparcelmedia.cpp
llviewerparcelmediaautoplay.cpp
llviewerparcelmgr.cpp
@@ -699,19 +722,13 @@ set(viewer_SOURCE_FILES
llvowater.cpp
llvowlsky.cpp
llwatchdog.cpp
- llwaterparammanager.cpp
- llwaterparamset.cpp
llwearableitemslist.cpp
llwearablelist.cpp
llweb.cpp
llwebprofile.cpp
llwind.cpp
llwindowlistener.cpp
- llwlanimator.cpp
- llwldaycycle.cpp
llwlhandlers.cpp
- llwlparammanager.cpp
- llwlparamset.cpp
llworld.cpp
llworldmap.cpp
llworldmapmessage.cpp
@@ -735,6 +752,7 @@ set(viewer_HEADER_FILES
llaisapi.h
llagent.h
llagentaccess.h
+ llagentbenefits.h
llagentcamera.h
llagentdata.h
llagentlanguage.h
@@ -791,7 +809,6 @@ set(viewer_HEADER_FILES
llcurrencyuimanager.h
llcylinder.h
lldateutil.h
- lldaycyclemanager.h
lldebugmessagebox.h
lldebugview.h
lldeferredsounds.h
@@ -814,7 +831,7 @@ set(viewer_HEADER_FILES
lldrawpoolwlsky.h
lldynamictexture.h
llemote.h
- llenvmanager.h
+ llenvironment.h
llestateinfomodel.h
lleventnotifier.h
lleventpoll.h
@@ -831,6 +848,7 @@ set(viewer_HEADER_FILES
llflexibleobject.h
llfloaterabout.h
llfloaterbvhpreview.h
+ llfloateraddpaymentmethod.h
llfloaterauction.h
llfloaterautoreplacesettings.h
llfloateravatar.h
@@ -848,23 +866,25 @@ set(viewer_HEADER_FILES
llfloaterbuycurrency.h
llfloaterbuycurrencyhtml.h
llfloaterbuyland.h
+ llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
+ llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
- llfloaterdeleteenvpreset.h
llfloaterdestinations.h
- llfloatereditdaycycle.h
- llfloatereditsky.h
- llfloatereditwater.h
- llfloaterenvironmentsettings.h
+ llfloatereditenvironmentbase.h
+ llfloatereditextdaycycle.h
+ llfloaterenvironmentadjust.h
llfloaterevent.h
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
+ llfloaterfixedenvironment.h
llfloaterfonttest.h
+ llfloaterforgetuser.h
llfloatergesture.h
llfloatergodtools.h
llfloatergotoline.h
@@ -875,6 +895,7 @@ set(viewer_HEADER_FILES
llfloaterhandler.h
llfloaterhelpbrowser.h
llfloaterhoverheight.h
+ llfloaterhowto.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterimnearbychat.h
@@ -897,6 +918,7 @@ set(viewer_HEADER_FILES
llfloatermodelpreview.h
llfloatermodeluploadbase.h
llfloatermyscripts.h
+ llfloatermyenvironment.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
@@ -912,12 +934,14 @@ set(viewer_HEADER_FILES
llfloaterperms.h
llfloaterpostprocess.h
llfloaterpreference.h
+ llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
llfloaterreporter.h
llfloaterregionrestarting.h
+ llfloatersavecamerapreset.h
llfloatersaveprefpreset.h
llfloatersceneloadstats.h
llfloaterscriptdebug.h
@@ -951,6 +975,7 @@ set(viewer_HEADER_FILES
llfolderviewmodelinventory.h
llfollowcam.h
llfriendcard.h
+ llflyoutcombobtn.h
llgesturelistener.h
llgesturemgr.h
llgiveinventory.h
@@ -994,6 +1019,7 @@ set(viewer_HEADER_FILES
llinventoryobserver.h
llinventorypanel.h
lljoystickbutton.h
+ llkeyconflict.h
lllandmarkactions.h
lllandmarklist.h
lllightconstants.h
@@ -1020,6 +1046,7 @@ set(viewer_HEADER_FILES
llmenuoptionpathfindingrebakenavmesh.h
llmeshrepository.h
llmimetypes.h
+ llmodelpreview.h
llmorphview.h
llmoveview.h
llmutelist.h
@@ -1043,7 +1070,10 @@ set(viewer_HEADER_FILES
llpanelblockedlist.h
llpanelclassified.h
llpanelcontents.h
+ llpaneleditsky.h
+ llpaneleditwater.h
llpaneleditwearable.h
+ llpanelenvironment.h
llpanelexperiencelisteditor.h
llpanelexperiencelog.h
llpanelexperiencepicker.h
@@ -1051,6 +1081,7 @@ set(viewer_HEADER_FILES
llpanelface.h
llpanelgenerictip.h
llpanelgroup.h
+ llpanelgroupcreate.h
llpanelgroupbulk.h
llpanelgroupbulkimpl.h
llpanelgroupbulkban.h
@@ -1090,12 +1121,14 @@ set(viewer_HEADER_FILES
llpanelplaceprofile.h
llpanelplaces.h
llpanelplacestab.h
+ llpanelpresetscamerapulldown.h
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
+ llpanelpulldown.h
llpanelvoicedevicesettings.h
llpanelvoiceeffect.h
llpaneltopinfobar.h
@@ -1158,6 +1191,9 @@ set(viewer_HEADER_FILES
llsecapi.h
llsechandler_basic.h
llselectmgr.h
+ llsetkeybinddialog.h
+ llsettingspicker.h
+ llsettingsvo.h
llsidepanelappearance.h
llsidepanelinventory.h
llsidepanelinventorysubpanel.h
@@ -1223,6 +1259,7 @@ set(viewer_HEADER_FILES
lltoolselectland.h
lltoolselectrect.h
lltracker.h
+ lltrackpicker.h
lltransientdockablefloater.h
lltransientfloatermgr.h
lltranslate.h
@@ -1234,6 +1271,7 @@ set(viewer_HEADER_FILES
llurl.h
llurldispatcher.h
llurldispatcherlistener.h
+ llurlfloaterdispatchhandler.h
llurlhistory.h
llurllineeditorctrl.h
llurlwhitelist.h
@@ -1262,7 +1300,7 @@ set(viewer_HEADER_FILES
llviewerjointattachment.h
llviewerjointmesh.h
llviewerjoystick.h
- llviewerkeyboard.h
+ llviewerinput.h
llviewerlayer.h
llviewermedia.h
llviewermediafocus.h
@@ -1274,6 +1312,7 @@ set(viewer_HEADER_FILES
llviewerobject.h
llviewerobjectlist.h
llvieweroctree.h
+ llviewerparcelaskplay.h
llviewerparcelmedia.h
llviewerparcelmediaautoplay.h
llviewerparcelmgr.h
@@ -1314,19 +1353,13 @@ set(viewer_HEADER_FILES
llvowater.h
llvowlsky.h
llwatchdog.h
- llwaterparammanager.h
- llwaterparamset.h
llwearableitemslist.h
llwearablelist.h
llweb.h
llwebprofile.h
llwind.h
llwindowlistener.h
- llwlanimator.h
- llwldaycycle.h
llwlhandlers.h
- llwlparammanager.h
- llwlparamset.h
llworld.h
llworldmap.h
llworldmapmessage.h
@@ -1566,20 +1599,12 @@ if (WINDOWS)
list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES})
endif (NOT USESYSTEMLIBS)
- find_library(DINPUT_LIBRARY dinput8 ${DIRECTX_LIBRARY_DIR})
- find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
- mark_as_advanced(
- DINPUT_LIBRARY
- DXGUID_LIBRARY
- )
-
# see EXP-1765 - theory is opengl32.lib needs to be included before gdi32.lib (windows libs)
set(viewer_LIBRARIES
opengl32
${WINDOWS_LIBRARIES}
comdlg32
- ${DINPUT_LIBRARY}
- ${DXGUID_LIBRARY}
+ dxguid
kernel32
odbc32
odbccp32
@@ -1610,6 +1635,10 @@ if (WINDOWS)
# causes those systems to run in a Windows 8 compatibility mode, which works.
LIST(APPEND viewer_SOURCE_FILES windows.manifest)
endif (ADDRESS_SIZE EQUAL 64)
+
+ if (OPENAL)
+ LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES})
+ endif (OPENAL)
endif (WINDOWS)
# Add the xui files. This is handy for searching for xui elements
@@ -1648,7 +1677,7 @@ set(viewer_APPSETTINGS_FILES
app_settings/grass.xml
app_settings/high_graphics.xml
app_settings/ignorable_dialogs.xml
- app_settings/keys.xml
+ app_settings/key_bindings.xml
app_settings/keywords_lsl_default.xml
app_settings/logcontrol.xml
app_settings/low_graphics.xml
@@ -1705,13 +1734,20 @@ if (OPENAL)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
endif (OPENAL)
-if (FMODEX)
- set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
- set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
-endif (FMODEX)
+if (FMODSTUDIO)
+ set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
+ set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY})
+endif (FMODSTUDIO)
set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
+if (HAVOK OR HAVOK_TPV)
+ set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK")
+endif (HAVOK OR HAVOK_TPV)
+
+# progress view disables/enables icons based on available packages
+set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
+
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
set_source_files_properties(${viewer_HEADER_FILES}
@@ -1765,6 +1801,11 @@ if (WINDOWS)
# be met. I'm looking forward to a source-code split-up project next year that will address this kind of thing.
# In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py
# and have the build deps get tracked *please* tell me about it.
+ # nat: https://cmake.org/cmake/help/v3.14/command/file.html
+ # "For example, the code
+ # file(STRINGS myfile.txt myfile)
+ # stores a list in the variable myfile in which each item is a line from the input file."
+ # And of course it's straightforward to read a text file in Python.
set(COPY_INPUT_DEPENDENCIES
# The following commented dependencies are determined at variably at build time. Can't do this here.
@@ -1783,15 +1824,11 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
- ${SHARED_LIB_STAGING_DIR}/Release/msvcr100.dll
- ${SHARED_LIB_STAGING_DIR}/Release/msvcp100.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcr100.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
+ ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll
@@ -1825,13 +1862,20 @@ if (WINDOWS)
)
endif (ADDRESS_SIZE EQUAL 64)
- if (FMODEX)
+ if (FMODSTUDIO)
+ list(APPEND COPY_INPUT_DEPENDENCIES
+ ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll
+ )
+ endif (FMODSTUDIO)
+
+ if (OPENAL)
list(APPEND COPY_INPUT_DEPENDENCIES
- ${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
+ ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/OpenAL32.dll
+ ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/alut.dll
)
- endif (FMODEX)
+ endif (OPENAL)
add_custom_command(
OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat
@@ -1842,6 +1886,8 @@ if (WINDOWS)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -1903,6 +1949,8 @@ if (WINDOWS)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -1970,6 +2018,7 @@ endif (WINDOWS)
# modern version.
target_link_libraries(${VIEWER_BINARY_NAME}
+ ${LEGACY_STDIO_LIBS}
${PNG_PRELOAD_ARCHIVES}
${ZLIB_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
@@ -1996,7 +2045,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
- ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
${DBUSGLIB_LIBRARIES}
${OPENGL_LIBRARIES}
@@ -2048,6 +2097,8 @@ if (LINUX)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -2074,6 +2125,8 @@ if (LINUX)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -2111,7 +2164,7 @@ if (DARWIN)
set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
- set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2018")
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2020")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication")
@@ -2150,6 +2203,8 @@ if (DARWIN)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
--bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
@@ -2184,6 +2239,8 @@ if (DARWIN)
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
+ "--fmodstudio=${FMODSTUDIO}"
+ "--openal=${OPENAL}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -2426,6 +2483,7 @@ if (LL_TESTS)
set_source_files_properties(
lllogininstance.cpp
PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp
LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
)
@@ -2475,7 +2533,7 @@ if (LL_TESTS)
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LIBRT_LIBRARY}
- ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
)
@@ -2520,7 +2578,6 @@ if (LL_TESTS)
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
- llwlparammanager.cpp
)
set_source_files_properties(
${viewer_TEST_SOURCE_FILES}
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index c8320dd521..22beed373e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.3.6
+6.4.21
diff --git a/indra/newview/app_settings/camera/Front.xml b/indra/newview/app_settings/camera/Front.xml
new file mode 100644
index 0000000000..39f44e11a8
--- /dev/null
+++ b/indra/newview/app_settings/camera/Front.xml
@@ -0,0 +1,142 @@
+<llsd>
+ <map>
+ <key>AppearanceCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>AvatarSitRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Avatar real sitting rotation used in preset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ </map>
+ <key>CameraAngle</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera field of view angle (Radians)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.047197551</real>
+ </map>
+ <key>CameraOffsetBuild</key>
+ <map>
+ <key>Comment</key>
+ <string>Default camera position relative to focus point when entering build mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-6</real>
+ <real>0</real>
+ <real>6</real>
+ </array>
+ </map>
+ <key>CameraOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar in Front View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>2.2</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ </array>
+ </map>
+ <key>CameraOffsetScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Scales the default offset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
+ <key>CameraZoomFraction</key>
+ <map>
+ <key>Comment</key>
+ <string>Mousewheel driven fraction of zoom</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.90322577953338623</real>
+ </map>
+ <key>EditCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering build mode, camera moves up above avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FocusOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the camera preset Front View (x-axis is forward)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ </array>
+ </map>
+ <key>PresetCameraActive</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of currently selected preference</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>Default</string>
+ </map>
+ <key>TrackFocusObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera tracks last object zoomed on</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/camera/Rear.xml b/indra/newview/app_settings/camera/Rear.xml
new file mode 100644
index 0000000000..8dc36353ce
--- /dev/null
+++ b/indra/newview/app_settings/camera/Rear.xml
@@ -0,0 +1,142 @@
+<llsd>
+ <map>
+ <key>AppearanceCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>AvatarSitRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Avatar real sitting rotation used in preset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ </map>
+ <key>CameraAngle</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera field of view angle (Radians)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.047197551</real>
+ </map>
+ <key>CameraOffsetBuild</key>
+ <map>
+ <key>Comment</key>
+ <string>Default camera position relative to focus point when entering build mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-6</real>
+ <real>0</real>
+ <real>6</real>
+ </array>
+ </map>
+ <key>CameraOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar in Rear View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-3</real>
+ <real>0</real>
+ <real>0.75</real>
+ </array>
+ </map>
+ <key>CameraOffsetScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Scales the default offset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
+ <key>CameraZoomFraction</key>
+ <map>
+ <key>Comment</key>
+ <string>Mousewheel driven fraction of zoom</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.90322577953338623</real>
+ </map>
+ <key>EditCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering build mode, camera moves up above avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FocusOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the camera preset Rear View (x-axis is forward)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PresetCameraActive</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of currently selected preference</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>Default</string>
+ </map>
+ <key>TrackFocusObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera tracks last object zoomed on</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/camera/Side.xml b/indra/newview/app_settings/camera/Side.xml
new file mode 100644
index 0000000000..089ab93a8f
--- /dev/null
+++ b/indra/newview/app_settings/camera/Side.xml
@@ -0,0 +1,142 @@
+<llsd>
+ <map>
+ <key>AppearanceCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>AvatarSitRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Avatar real sitting rotation used in preset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ </map>
+ <key>CameraAngle</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera field of view angle (Radians)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.047197551</real>
+ </map>
+ <key>CameraOffsetBuild</key>
+ <map>
+ <key>Comment</key>
+ <string>Default camera position relative to focus point when entering build mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-6</real>
+ <real>0</real>
+ <real>6</real>
+ </array>
+ </map>
+ <key>CameraOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar in Side View</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-1.0</real>
+ <real>0.7</real>
+ <real>0.5</real>
+ </array>
+ </map>
+ <key>CameraOffsetScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Scales the default offset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
+ <key>CameraZoomFraction</key>
+ <map>
+ <key>Comment</key>
+ <string>Mousewheel driven fraction of zoom</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.90322577953338623</real>
+ </map>
+ <key>EditCameraMovement</key>
+ <map>
+ <key>Comment</key>
+ <string>When entering build mode, camera moves up above avatar</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FocusOffsetRearView</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the camera preset Side View (x-axis is forward)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>1.5</real>
+ <real>0.7</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PresetCameraActive</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of currently selected preference</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>Default</string>
+ </map>
+ <key>TrackFocusObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera tracks last object zoomed on</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index e4e1cdcf44..4e186292f7 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -407,5 +407,14 @@
<integer>1</integer>
<!-- Special case. Mapped to settings procedurally. -->
</map>
+
+ <key>skipupdatecheck</key>
+ <map>
+ <key>desc</key>
+ <string>Skips update check at startup.</string>
+ <key>map-to</key>
+ <string>CmdLineSkipUpdater</string>
+ </map>
+
</map>
</llsd>
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index fa37dea51b..d0480ca47e 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -88,8 +88,10 @@
icon="Command_HowTo_Icon"
label_ref="Command_HowTo_Label"
tooltip_ref="Command_HowTo_Tooltip"
- execute_function="Help.ToggleHowTo"
- is_running_function="Help.HowToVisible"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="guidebook"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="guidebook"
/>
<command name="inventory"
available_in_toybox="true"
@@ -150,16 +152,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="moveview"
/>
- <command name="outbox"
- available_in_toybox="false"
- icon="Command_Outbox_Icon"
- label_ref="Command_Outbox_Label"
- tooltip_ref="Command_Outbox_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="outbox"
- is_running_function="Floater.IsOpen"
- is_running_parameters="outbox"
- />
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"
@@ -273,4 +265,15 @@
is_running_function="Floater.IsOpen"
is_running_parameters="grid_status"
/>
+ <command name="myenvironments"
+ available_in_toybox="true"
+ is_flashing_allowed="true"
+ icon="Command_Environments_Icon"
+ label_ref="Command_Environments_Label"
+ tooltip_ref="Command_Environments_Tooltip"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="my_environments"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="my_environments"
+ />
</commands>
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
index c38b3fcda4..662f7e39dd 100644
--- a/indra/newview/app_settings/high_graphics.xml
+++ b/indra/newview/app_settings/high_graphics.xml
@@ -33,8 +33,6 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <VertexShaderEnable value="TRUE"/>
- <!--NO SHADERS-->
<WindLightUseAtmosShaders value="TRUE"/>
<!--Deferred Shading-->
<RenderDeferred value="FALSE"/>
diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/key_bindings.xml
index a8037fec05..4f6deb1f98 100644
--- a/indra/newview/app_settings/keys.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -28,34 +28,11 @@
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
- <binding key="A" mask="SHIFT" command="slide_left"/>
- <binding key="D" mask="SHIFT" command="slide_right"/>
- <binding key="W" mask="SHIFT" command="push_forward"/>
- <binding key="S" mask="SHIFT" command="push_backward"/>
- <binding key="E" mask="SHIFT" command="jump"/>
- <binding key="C" mask="SHIFT" command="push_down"/>
- <binding key="F" mask="SHIFT" command="toggle_fly"/>
-
<binding key="SPACE" mask="NONE" command="stop_moving"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
- <binding key="LEFT" mask="SHIFT" command="slide_left"/>
- <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
- <binding key="UP" mask="SHIFT" command="push_forward"/>
- <binding key="DOWN" mask="SHIFT" command="push_backward"/>
- <binding key="PGUP" mask="SHIFT" command="jump"/>
- <binding key="PGDN" mask="SHIFT" command="push_down"/>
-
- <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
- <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
- <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
- <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
- <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
- <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
- <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
- <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
- <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
+ <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
</first_person>
<third_person>
<binding key="A" mask="NONE" command="turn_left"/>
@@ -64,15 +41,10 @@
<binding key="D" mask="SHIFT" command="slide_right"/>
<binding key="W" mask="NONE" command="push_forward"/>
<binding key="S" mask="NONE" command="push_backward"/>
- <binding key="W" mask="SHIFT" command="push_forward"/>
- <binding key="S" mask="SHIFT" command="push_backward"/>
<binding key="E" mask="NONE" command="jump"/>
<binding key="C" mask="NONE" command="push_down"/>
- <binding key="E" mask="SHIFT" command="jump"/>
- <binding key="C" mask="SHIFT" command="push_down"/>
<binding key="F" mask="NONE" command="toggle_fly"/>
- <binding key="F" mask="SHIFT" command="toggle_fly"/>
<binding key="SPACE" mask="NONE" command="stop_moving"/>
<binding key="ENTER" mask="NONE" command="start_chat"/>
@@ -84,13 +56,8 @@
<binding key="RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="UP" mask="NONE" command="push_forward"/>
<binding key="DOWN" mask="NONE" command="push_backward"/>
- <binding key="UP" mask="SHIFT" command="push_forward"/>
- <binding key="DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PGUP" mask="NONE" command="jump"/>
<binding key="PGDN" mask="NONE" command="push_down"/>
- <binding key="PGUP" mask="SHIFT" command="jump"/>
- <binding key="PGDN" mask="SHIFT" command="push_down"/>
- <binding key="HOME" mask="SHIFT" command="toggle_fly"/>
<binding key="HOME" mask="NONE" command="toggle_fly"/>
<binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
@@ -99,20 +66,12 @@
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="NONE" command="push_forward"/>
<binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
- <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
- <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
<binding key="PAD_PGUP" mask="NONE" command="jump"/>
<binding key="PAD_PGDN" mask="NONE" command="push_down"/>
- <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
- <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
<binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
- <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
<binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
- <binding key="PAD_CENTER" mask="SHIFT" command="stop_moving"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
- <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
- <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
<!--Camera controls in third person on Alt-->
<binding key="LEFT" mask="ALT" command="spin_around_cw"/>
@@ -139,28 +98,14 @@
<binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
<!--mimic alt zoom behavior with keyboard only-->
- <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
- <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="W" mask="CTL_ALT" command="spin_over"/>
<binding key="S" mask="CTL_ALT" command="spin_under"/>
- <binding key="E" mask="CTL_ALT" command="spin_over"/>
- <binding key="C" mask="CTL_ALT" command="spin_under"/>
- <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
- <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="UP" mask="CTL_ALT" command="spin_over"/>
<binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
- <binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
- <binding key="PGDN" mask="CTL_ALT" command="spin_under"/>
- <binding key="PAD_LEFT" mask="CTL_ALT" command="spin_around_cw"/>
- <binding key="PAD_RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
<binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
- <binding key="PAD_PGUP" mask="CTL_ALT" command="spin_over"/>
- <binding key="PAD_PGDN" mask="CTL_ALT" command="spin_under"/>
- <binding key="PAD_ENTER" mask="CTL_ALT" command="start_chat"/>
- <binding key="PAD_DIVIDE" mask="CTL_ALT" command="start_gesture"/>
<!--Therefore pan on Alt-Shift-->
<binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
@@ -179,63 +124,10 @@
<binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
- </third_person>
- <!-- Basic editing camera control -->
- <edit>
- <binding key="A" mask="NONE" command="spin_around_cw"/>
- <binding key="D" mask="NONE" command="spin_around_ccw"/>
- <binding key="W" mask="NONE" command="move_forward"/>
- <binding key="S" mask="NONE" command="move_backward"/>
- <binding key="E" mask="NONE" command="spin_over"/>
- <binding key="C" mask="NONE" command="spin_under"/>
- <binding key="ENTER" mask="NONE" command="start_chat"/>
- <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
- <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
- <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-
- <binding key="LEFT" mask="NONE" command="spin_around_cw"/>
- <binding key="RIGHT" mask="NONE" command="spin_around_ccw"/>
- <binding key="UP" mask="NONE" command="move_forward"/>
- <binding key="DOWN" mask="NONE" command="move_backward"/>
- <binding key="PGUP" mask="NONE" command="spin_over"/>
- <binding key="PGDN" mask="NONE" command="spin_under"/>
-
- <binding key="A" mask="SHIFT" command="pan_left"/>
- <binding key="D" mask="SHIFT" command="pan_right"/>
- <binding key="W" mask="SHIFT" command="pan_up"/>
- <binding key="S" mask="SHIFT" command="pan_down"/>
-
- <binding key="LEFT" mask="SHIFT" command="pan_left"/>
- <binding key="RIGHT" mask="SHIFT" command="pan_right"/>
- <binding key="UP" mask="SHIFT" command="pan_up"/>
- <binding key="DOWN" mask="SHIFT" command="pan_down"/>
-
- <!--Walking works with ALT held down.-->
- <binding key="A" mask="ALT" command="slide_left"/>
- <binding key="D" mask="ALT" command="slide_right"/>
- <binding key="W" mask="ALT" command="push_forward"/>
- <binding key="S" mask="ALT" command="push_backward"/>
- <binding key="E" mask="ALT" command="jump"/>
- <binding key="C" mask="ALT" command="push_down"/>
-
- <binding key="LEFT" mask="ALT" command="slide_left"/>
- <binding key="RIGHT" mask="ALT" command="slide_right"/>
- <binding key="UP" mask="ALT" command="push_forward"/>
- <binding key="DOWN" mask="ALT" command="push_backward"/>
- <binding key="PGUP" mask="ALT" command="jump"/>
- <binding key="PGDN" mask="ALT" command="push_down"/>
- <binding key="HOME" mask="ALT" command="toggle_fly"/>
-
- <binding key="PAD_LEFT" mask="ALT" command="slide_left"/>
- <binding key="PAD_RIGHT" mask="ALT" command="slide_right"/>
- <binding key="PAD_UP" mask="ALT" command="push_forward"/>
- <binding key="PAD_DOWN" mask="ALT" command="push_backward"/>
- <binding key="PAD_PGUP" mask="ALT" command="jump"/>
- <binding key="PAD_PGDN" mask="ALT" command="push_down"/>
- <binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
- <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
- </edit>
+ <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+ <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
+ </third_person>
<sitting>
<binding key="A" mask="ALT" command="spin_around_cw"/>
<binding key="D" mask="ALT" command="spin_around_ccw"/>
@@ -251,15 +143,11 @@
<binding key="PGUP" mask="ALT" command="spin_over"/>
<binding key="PGDN" mask="ALT" command="spin_under"/>
- <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
- <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="W" mask="CTL_ALT" command="spin_over"/>
<binding key="S" mask="CTL_ALT" command="spin_under"/>
<binding key="E" mask="CTL_ALT" command="spin_over"/>
<binding key="C" mask="CTL_ALT" command="spin_under"/>
- <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
- <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
<binding key="UP" mask="CTL_ALT" command="spin_over"/>
<binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
<binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
@@ -294,23 +182,23 @@
<binding key="A" mask="SHIFT" command="slide_left"/>
<binding key="D" mask="SHIFT" command="slide_right"/>
<binding key="W" mask="SHIFT" command="move_forward_sitting"/>
- <binding key="S" mask="SHIFT" command="move_backward_sitting"/>
- <binding key="E" mask="SHIFT" command="spin_over_sitting"/>
- <binding key="C" mask="SHIFT" command="spin_under_sitting"/>
+ <binding key="S" mask="SHIFT" command="move_backward_sitting"/>
+ <binding key="E" mask="SHIFT" command="spin_over_sitting"/>
+ <binding key="C" mask="SHIFT" command="spin_under_sitting"/>
<binding key="LEFT" mask="SHIFT" command="slide_left"/>
<binding key="RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="UP" mask="SHIFT" command="move_forward_sitting"/>
- <binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
- <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
- <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
+ <binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
+ <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
+ <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
<binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
<binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/>
- <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
- <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
- <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/>
+ <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
+ <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
+ <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/>
<binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
@@ -334,6 +222,8 @@
<binding key="ENTER" mask="NONE" command="start_chat"/>
<binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+
+ <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
</sitting>
<edit_avatar>
<!--Avatar editing camera controls-->
@@ -359,5 +249,7 @@
<binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
<binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
<binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+
+ <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
</edit_avatar>
-</keys> \ No newline at end of file
+</keys>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index df3f67a5a1..0ee8e7a059 100644
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -33,8 +33,6 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <VertexShaderEnable value="FALSE"/>
- <!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
<!--No Deferred Shading-->
<RenderDeferred value="FALSE"/>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index a10c02b79f..c89e060307 100644
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -33,8 +33,6 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <VertexShaderEnable value="TRUE"/>
- <!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
<!--No Deferred Shading-->
<RenderDeferred value="FALSE"/>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f73f925635..a2933b85a5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1252,6 +1252,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BulkChangeIncludeSettings</key>
+ <map>
+ <key>Comment</key>
+ <string>Bulk permission changes affect environment settings</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>
@@ -1499,6 +1510,21 @@
<real>0.5</real>
</array>
</map>
+ <key>CameraOffsetCustomPreset</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial camera offset from avatar for the custom camera preset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-3.0</real>
+ <real>0.0</real>
+ <real>0.75</real>
+ </array>
+ </map>
<key>CameraOffsetScale</key>
<map>
<key>Comment</key>
@@ -1510,6 +1536,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>CameraZoomFraction</key>
+ <map>
+ <key>Comment</key>
+ <string>Mousewheel driven fraction of zoom</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.9</real>
+ </map>
<key>CameraPosOnLogout</key>
<map>
<key>Comment</key>
@@ -1547,7 +1584,7 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>CameraPreset</key>
+ <key>CameraPreset</key> <!-- deprecated (see SL-12429) -->
<map>
<key>Comment</key>
<string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
@@ -1929,7 +1966,18 @@
<key>Value</key>
<string/>
</map>
- <key>ConnectAsGod</key>
+ <key>CmdLineSkipUpdater</key>
+ <map>
+ <key>Comment</key>
+ <string>Command line skip updater check.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ConnectAsGod</key>
<map>
<key>Comment</key>
<string>Log in a god if you have god access.</string>
@@ -3494,7 +3542,7 @@
<key>DoubleClickAutoPilot</key>
<map>
<key>Comment</key>
- <string>Enable double-click auto pilot</string>
+ <string>(Obsolete)Enable double-click auto pilot</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -3502,10 +3550,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DoubleClickTeleport</key>
+ <key>DoubleClickTeleport</key>
<map>
<key>Comment</key>
- <string>Enable double-click to teleport where allowed</string>
+ <string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -4356,6 +4404,37 @@
<real>1.0</real>
</array>
</map>
+ <key>FocusOffsetCustomPreset</key>
+ <map>
+ <key>Comment</key>
+ <string>Initial focus point offset relative to avatar for the custom camera preset (x-axis is forward)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3D</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>AvatarSitRotation</key>
+ <map>
+ <key>Comment</key>
+ <string>Avatar real sitting rotation used in preset</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ </map>
<key>FocusPosOnLogout</key>
<map>
<key>Comment</key>
@@ -4646,6 +4725,17 @@
<key>Value</key>
<string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&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>
</map>
+ <key>GuidebookURL</key>
+ <map>
+ <key>Comment</key>
+ <string>URL for Guidebook content</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>http://guidebooks.secondlife.io/welcome/index.html</string>
+ </map>
<key>HighResSnapshot</key>
<map>
<key>Comment</key>
@@ -4913,7 +5003,7 @@
<key>InventoryOutboxDisplayBoth</key>
<map>
<key>Comment</key>
- <string>Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
+ <string>(Deprecated) Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -5163,6 +5253,17 @@
<key>Value</key>
<string />
</map>
+ <key>JoystickDeviceUUID</key>
+ <map>
+ <key>Comment</key>
+ <string>Preffered device ID.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>JoystickMouselookYaw</key>
<map>
<key>Comment</key>
@@ -5845,7 +5946,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>http://map.secondlife.com.s3.amazonaws.com/</string>
+ <string>https://map.secondlife.com/</string>
</map>
<key>CurrentMapServerURL</key>
<map>
@@ -6496,7 +6597,7 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>MemoryFailurePreventionEnabled</key>
+ <key>MemoryFailurePreventionEnabled</key> <!-- deprecated, only used for obsolete-in-2020 Intel 965 Express GPU -->
<map>
<key>Comment</key>
<string>If set, the viewer will quit to avoid crash when memory failure happens</string>
@@ -6640,7 +6741,7 @@
<integer>600</integer>
</map>
<key>MigrateCacheDirectory</key>
- <map>
+ <map>
<key>Comment</key>
<string>Check for old version of disk cache to migrate to current location</string>
<key>Persist</key>
@@ -6716,6 +6817,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>MouseMoon</key>
+ <map>
+ <key>Comment</key>
+ <string />
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MuteAmbient</key>
<map>
<key>Comment</key>
@@ -7494,11 +7606,11 @@
<key>ParcelMediaAutoPlayEnable</key>
<map>
<key>Comment</key>
- <string>Auto play parcel media when available</string>
+ <string>Auto play parcel media when available. 0 - Do not autoplay; 1- Autoplay; 2 - Ask</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
@@ -7879,7 +7991,6 @@
<key>Value</key>
<integer>13</integer>
</map>
-
<key>PreviewAmbientColor</key>
<map>
<key>Comment</key>
@@ -7896,8 +8007,6 @@
<real>1.0</real>
</array>
</map>
-
-
<key>PreviewDiffuse0</key>
<map>
<key>Comment</key>
@@ -8184,7 +8293,7 @@
<key>PushToTalkButton</key>
<map>
<key>Comment</key>
- <string>Which button or keyboard key is used for push-to-talk</string>
+ <string>(Obsolete)Which button or keyboard key is used for push-to-talk</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8344,7 +8453,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.125</real>
+ <real>0.02</real>
</map>
<key>MediaRollOffMin</key>
<map>
@@ -8355,7 +8464,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>10.0</real>
+ <real>40.0</real>
</map>
<key>MediaRollOffMax</key>
<map>
@@ -8366,7 +8475,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>30.0</real>
+ <real>80.0</real>
</map>
<key>RecentItemsSortOrder</key>
<map>
@@ -8434,6 +8543,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RememberUser</key>
+ <map>
+ <key>Comment</key>
+ <string>Keep user name for next login</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RememberPassword</key>
<map>
<key>Comment</key>
@@ -8525,6 +8645,28 @@
</array>
</map>
+ <key>RenderAlphaBatchFullbrights</key>
+ <map>
+ <key>Comment</key>
+ <string>Render fullbright alpha content more efficiently, but with possible visual differences from prev viewers.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderAlphaBatchEmissives</key>
+ <map>
+ <key>Comment</key>
+ <string>Render emissive alpha content more efficiently, but with possible visual differences from prev viewers.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderAnisotropic</key>
<map>
<key>Comment</key>
@@ -8982,7 +9124,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.03</real>
+ <real>0.1</real>
</map>
<key>RenderDebugPipeline</key>
<map>
@@ -9154,7 +9296,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>-0.008</real>
+ <real>-0.004</real>
</map>
<key>RenderShadowOffset</key>
<map>
@@ -9276,7 +9418,7 @@
<key>RenderShadowResolutionScale</key>
<map>
<key>Comment</key>
- <string>Scale of shadow map resolution vs. screen resolution</string>
+ <string>Scale of shadow map resolution vs. screen resolution (only positivie values are allowed)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10255,6 +10397,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderUseAdvancedAtmospherics</key>
+ <map>
+ <key>Comment</key>
+ <string>Use fancy precomputed atmospherics and stuff.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderUseTriStrips</key>
<map>
<key>Comment</key>
@@ -11970,6 +12123,21 @@
<key>Value</key>
<real>0.300000011921</real>
</map>
+ <key>SkyMoonDefaultPosition</key>
+ <map>
+ <key>Comment</key>
+ <string>Default position of sun in sky (direction in world coordinates)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>-1.0</real>
+ <real>0.0</real>
+ <real>-0.1</real>
+ </array>
+ </map>
<key>SkyNightColorShift</key>
<map>
<key>Comment</key>
@@ -12286,6 +12454,39 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>AmbientDisable</key>
+ <map>
+ <key>Comment</key>
+ <string>If TRUE, ambient light has no effect</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>SunlightDisable</key>
+ <map>
+ <key>Comment</key>
+ <string>If TRUE, sunlight has no effect</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>LocalLightDisable</key>
+ <map>
+ <key>Comment</key>
+ <string>If TRUE, local lights have no effect</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>TextureDiscardLevel</key>
<map>
<key>Comment</key>
@@ -14134,6 +14335,7 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <!-- SL-12594 removes fixed function rendering
<key>VertexShaderEnable</key>
<map>
<key>Comment</key>
@@ -14145,6 +14347,7 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <-->
<key>VivoxAutoPostCrashDumps</key>
<map>
<key>Comment</key>
@@ -14233,10 +14436,56 @@
<key>Value</key>
<integer>44125</integer>
</map>
- <key>VoiceCallsFriendsOnly</key>
+
+ <key>VivoxVadAuto</key>
+ <map>
+ <key>Comment</key>
+ <string>A flag indicating if the automatic VAD is enabled (1) or disabled (0). The individual settings are ignored if the auto-mode is enabled</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>VivoxVadHangover</key>
+ <map>
+ <key>Comment</key>
+ <string>The time (in milliseconds) that it takes or the VAD to switch back to silence from speech mode after the last speech frame has been detected</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>2000</integer>
+ </map>
+ <key>VivoxVadNoiseFloor</key>
+ <map>
+ <key>Comment</key>
+ <string>A dimensionless value between 0 and 20000 (default 576) that controls the maximum level at which the noise floor may be set at by the VAD's noise tracking</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>576</integer>
+ </map>
+ <key>VivoxVadSensitivity</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>VoiceCallsFriendsOnly</key>
<map>
<key>Comment</key>
- <string>Only accept voice calls from residents on your friends list</string>
+ <string>(Deprecated) Only accept voice calls from residents on your friends list</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -14827,6 +15076,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>sunbeacon</key>
+ <map>
+ <key>Comment</key>
+ <string>Show direction to the Sun</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>moonbeacon</key>
+ <map>
+ <key>Comment</key>
+ <string>Show direction to the Moon</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowDeviceSettings</key>
<map>
<key>Comment</key>
@@ -15353,7 +15624,7 @@
<key>ClickToWalk</key>
<map>
<key>Comment</key>
- <string>Click in world to walk to location</string>
+ <string>(obsolete)Click in world to walk to location</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -15789,6 +16060,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SettingsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created Environment setting 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>SettingsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created Environment setting 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>DefaultUploadPermissionsConverted</key>
<map>
<key>Comment</key>
@@ -16156,7 +16449,7 @@
<key>FMODExProfilerEnable</key>
<map>
<key>Comment</key>
- <string>Enable profiler tool if using FMOD Ex</string>
+ <string>Enable profiler tool if using FMOD Ex or FMOD Studio</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -16167,7 +16460,7 @@
<key>FMODExDecodeBufferSize</key>
<map>
<key>Comment</key>
- <string>Sets the streaming decode buffer size (in milliseconds)</string>
+ <string>Sets the streaming decode buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -16178,7 +16471,7 @@
<key>FMODExStreamBufferSize</key>
<map>
<key>Comment</key>
- <string>Sets the streaming buffer size (in milliseconds)</string>
+ <string>Sets the streaming buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -16321,6 +16614,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>CameraOpacity</key>
+ <map>
+ <key>Comment</key>
+ <string>Opacity of the Camera Controls floater</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>PresetCameraActive</key>
+ <map>
+ <key>Comment</key>
+ <string>Name of currently selected preference</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>Rear View</string>
+ </map>
+ <key>CameraPresetType</key>
+ <map>
+ <key>Comment</key>
+ <string>Preset camera position - view (0 - rear, 1 - front, 2 - group, 3 - custom)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>HoverHeightAffectsCamera</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera view is affected by Hover Height setting</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>CefVerboseLog</key>
<map>
<key>Comment</key>
@@ -16346,3 +16683,4 @@
</map>
</llsd>
+
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 8f4ca6c633..537744b44c 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -220,6 +220,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>VoiceCallsFriendsOnly</key>
+ <map>
+ <key>Comment</key>
+ <string>Only accept voice calls and receive IMs from residents on your friends list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>VoiceEffectDefault</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index 19203ab670..0543a26642 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
@@ -34,7 +34,7 @@ VARYING vec2 vary_texcoord0;
uniform vec4 color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
@@ -62,7 +62,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0,0,0,0));
+ vec4 col = calcLighting(pos.xyz, norm, color);
vertex_color = col;
}
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index 82db15c3ae..fac1599c6b 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
@@ -36,7 +36,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -52,7 +52,7 @@ void main()
calcAtmospherics(pos.xyz);
vec4 specular = vec4(1.0);
- vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));
+ vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular);
vertex_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index b9c8f34cb0..dc484317e9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -22,7 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+//class1/deferred/alphaF.glsl
+
#extension GL_ARB_texture_rectangle : enable
/*[EXTRA_CODE_HERE]*/
@@ -37,39 +39,9 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform float display_gamma;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-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 env_mat;
-uniform mat3 ssao_effect_mat;
-
uniform vec3 sun_dir;
-
-#if HAS_SHADOW
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-
-uniform vec2 shadow_res;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float shadow_bias;
-
-#endif
+uniform vec3 moon_dir;
#ifdef USE_DIFFUSE_TEX
uniform sampler2D diffuseMap;
@@ -81,551 +53,254 @@ VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color;
+VARYING vec4 vertex_color; //vertex color should be treated as sRGB
#endif
-vec3 vary_PositionEye;
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
+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 vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
+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);
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+#ifdef HAS_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
-vec3 decode_normal (vec2 enc)
-{
- 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 getAmbientClamp();
-vec3 calcDirectionalLight(vec3 n, vec3 l)
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
{
- float a = max(dot(n,l),0.0);
- a = pow(a, 1.0/1.3);
- return vec3(a,a,a);
-}
+ vec3 col = vec3(0);
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
//get light vector
vec3 lv = lp.xyz-v;
-
+
//get distance
- float d = length(lv);
-
+ float dist = length(lv);
float da = 1.0;
- vec3 col = vec3(0);
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
+ /*if (dist > 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 && la > 0.0)
{
+ dist /= la;
+
//normalize light vector
lv = normalize(lv);
//distance attenuation
- float dist = d/la;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ 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 *= max(dot(n, lv), 0.0);
-
- float lit = max(da * dist_atten,0.0);
-
- col = light_col * lit * diffuse;
-
- // no spec for alpha shader...
- }
-
- return max(col, vec3(0.0,0.0,0.0));
+ 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;
}
-#if HAS_SHADOW
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
+void main()
{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-#endif
+ 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;
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- float es = -(dot(view, waterPlane.xyz));
+ float shadow = 1.0f;
- //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;
-
- 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;
-}
+#ifdef HAS_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
#endif
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * 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);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
+#ifdef USE_DIFFUSE_TEX
+ vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
+#endif
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
+#ifdef USE_INDEXED_TEX
+ vec4 diffuse_tap = diffuseLookup(vary_texcoord0.xy);
+#endif
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
+ vec4 diffuse_srgb = diffuse_tap;
+ vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
-vec3 scaleDownLight(vec3 light)
-{
- return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
+#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;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
+
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < 0.01)
+ {
+ discard;
+ }
+#else
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
-vec3 scaleUpLight(vec3 light)
-{
- return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
+ float final_alpha = diffuse_linear.a;
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
-}
+#ifdef USE_VERTEX_COLOR
+ final_alpha *= vertex_color.a;
+ diffuse_srgb.rgb *= vertex_color.rgb;
+ diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb);
+#endif
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
-}
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
- vec3 ones = vec3(1.0f, 1.0f, 1.0f);
+ calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
- light = ones - clamp(light, zeroes, ones);
- light = ones - pow(light, gamma.xxx);
+ vec2 abnormal = encode_normal(norm.xyz);
- return light;
-}
+ 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);
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
+ vec4 color = vec4(0.0);
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
+ color.a = final_alpha;
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- vec4 pos = vec4(vary_position, 1.0);
-
- float shadow = 1.0;
-
-#if HAS_SHADOW
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- shadow = 0.0;
-
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-#endif
+ vec3 sun_contrib = min(final_da, shadow) * sunlit;
-#ifdef USE_INDEXED_TEX
- vec4 diff = diffuseLookup(vary_texcoord0.xy);
-#else
- vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+#if !defined(AMBIENT_KILL)
+ color.rgb = amblit;
+ color.rgb *= ambient;
#endif
-#ifdef FOR_IMPOSTOR
- vec4 color;
- color.rgb = diff.rgb;
- color.a = 1.0;
+vec3 post_ambient = color.rgb;
-#ifdef USE_VERTEX_COLOR
- float final_alpha = diff.a * vertex_color.a;
- diff.rgb *= vertex_color.rgb;
-#else
- float final_alpha = diff.a;
-#endif
-
- // Insure we don't pollute depth with invis pixels in impostor rendering
- //
- if (final_alpha < 0.01)
- {
- discard;
- }
-#else
-
-#ifdef USE_VERTEX_COLOR
- float final_alpha = diff.a * vertex_color.a;
- diff.rgb *= vertex_color.rgb;
-#else
- float final_alpha = diff.a;
+#if !defined(SUNLIGHT_KILL)
+ color.rgb += sun_contrib;
#endif
+vec3 post_sunlight = color.rgb;
- vec4 gamma_diff = diff;
- diff.rgb = srgb_to_linear(diff.rgb);
+ color.rgb *= diffuse_srgb.rgb;
- vec3 norm = vary_norm;
+vec3 post_diffuse = color.rgb;
- calcAtmospherics(pos.xyz, 1.0);
+ color.rgb = atmosFragLighting(color.rgb, additive, atten);
- vec2 abnormal = encode_normal(norm.xyz);
- norm.xyz = decode_normal(abnormal.xy);
+vec3 post_atmo = color.rgb;
- float da = dot(norm.xyz, sun_dir.xyz);
+ vec4 light = vec4(0,0,0,0);
+
+ color.rgb = scaleSoftClipFrag(color.rgb);
- float final_da = da;
- final_da = min(final_da, shadow);
- final_da = max(final_da, 0.0f);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
+ //convert to linear before applying local lights
+ color.rgb = srgb_to_linear(color.rgb);
- vec4 color = 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);
- color.rgb = atmosAmbient(color.rgb);
- color.a = final_alpha;
-
- float ambient = abs(da);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- color.rgb *= ambient;
- color.rgb += atmosAffectDirectionalLight(final_da);
- color.rgb *= gamma_diff.rgb;
-
- //color.rgb = mix(diff.rgb, color.rgb, final_alpha);
-
- color.rgb = atmosLighting(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
- vec4 light = vec4(0,0,0,0);
-
- color.rgb = srgb_to_linear(color.rgb);
-
- #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- // keep it linear
- //
- color.rgb += light.rgb;
-
- // straight to display gamma, we're post-deferred
- //
- color.rgb = linear_to_srgb(color.rgb);
+ // sum local light contrib in linear colorspace
+#if !defined(LOCAL_LIGHT_KILL)
+ color.rgb += light.rgb;
+#endif
+ // 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 = applyWaterFogDeferred(pos.xyz, color);
-#endif
+ color = applyWaterFogView(pos.xyz, color);
+#endif // WATER_FOG
#endif
-
- frag_color = color;
+
+ frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
new file mode 100644
index 0000000000..23adbded5e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
@@ -0,0 +1,123 @@
+/**
+ * @file class1/deferred/aoUtil.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 noiseMap;
+uniform sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+
+uniform float ssao_radius;
+uniform float ssao_max_radius;
+uniform float ssao_factor;
+uniform float ssao_factor_inv;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+vec2 getScreenCoordinateAo(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);
+}
+
+float getDepthAo(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen).r;
+ return depth;
+}
+
+vec4 getPositionAo(vec2 pos_screen)
+{
+ float depth = getDepthAo(pos_screen);
+ vec2 sc = getScreenCoordinateAo(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;
+}
+
+vec2 getKern(int i)
+{
+ vec2 kern[8];
+ // exponentially (^2) distant occlusion samples spread around origin
+ kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
+ kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
+ kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
+ kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
+ kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
+ kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
+ kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
+ kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
+
+ return kern[i];
+}
+
+//calculate decreases in ambient lighting when crowded out (SSAO)
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
+{
+ float ret = 1.0;
+ vec3 pos_world = pos.xyz;
+ vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;
+
+ float angle_hidden = 0.0;
+ float points = 0;
+
+ float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
+
+ // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
+ for (int i = 0; i < 8; i++)
+ {
+ vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
+ vec3 samppos_world = getPositionAo(samppos_screen).xyz;
+
+ vec3 diff = pos_world - samppos_world;
+ float dist2 = dot(diff, diff);
+
+ // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
+ // --> solid angle shrinking by the square of distance
+ //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
+ //(k should vary inversely with # of samples, but this is taken care of later)
+
+ float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
+ angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
+
+ // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
+ float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
+ points = points + diffz_val;
+ }
+
+ angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
+
+ float points_val = (points > 0.0) ? 1.0 : 0.0;
+ ret = (1.0 - (points_val * angle_hidden));
+
+ ret = max(ret, 0.0);
+ return min(ret, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
index 22c9a4d14e..8e9a5fcd41 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
@@ -22,6 +22,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index 3f90600ace..0fa0edfd67 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -41,7 +41,7 @@ void main()
vec4 p = projection_matrix * vec4(pos, 1.0);
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
index c8ddefac26..bbdc8fdd1c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
@@ -29,17 +29,13 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
@@ -59,41 +55,7 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
void main()
{
@@ -137,7 +99,7 @@ void main()
col.rgb = vec3(0,0,0);
// Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
+ col.rgb = atmosAmbient();
vary_ambient = col.rgb*color.rgb;
vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 662c762bca..60d83cc623 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -36,11 +38,7 @@ uniform float minimum_alpha;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index b809b73973..50020a50d8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -22,7 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -31,7 +33,7 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -39,7 +41,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/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index bde1ad4e9f..91b25613e0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -53,7 +53,7 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
-#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/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index cbd8d2ebfc..596d0274af 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -33,7 +33,6 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
@@ -45,100 +44,68 @@ uniform float kern_scale;
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = decode_normal(norm.xy); // unpack norm
-
- vec3 pos = getPosition(tc).xyz;
- vec4 ccol = texture2DRect(lightMap, tc).rgba;
-
- vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
- dlt /= max(-pos.z*dist_factor, 1.0);
-
- vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
- vec4 col = defined_weight.xyxx * ccol;
-
- // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
- float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
-
- // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
- float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
- tc_mod -= floor(tc_mod);
- tc_mod *= 2.0;
- tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
-
- for (int i = 1; i < 4; i++)
- {
- vec2 samptc = tc + kern[i].z*dlt;
- 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;
- }
- }
-
- for (int i = 1; i < 4; i++)
- {
- vec2 samptc = tc - kern[i].z*dlt;
- 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 /= defined_weight.xyxx;
- col.y *= col.y;
-
- frag_color = col;
+ vec3 norm = getNorm(tc);
+ vec3 pos = getPosition(tc).xyz;
+ vec4 ccol = texture2DRect(lightMap, tc).rgba;
+
+ vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
+ dlt /= max(-pos.z*dist_factor, 1.0);
+
+ vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
+ vec4 col = defined_weight.xyxx * ccol;
+
+ // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
+ float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
+
+ // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
+ float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
+ tc_mod -= floor(tc_mod);
+ tc_mod *= 2.0;
+ tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
+
+ for (int i = 1; i < 4; i++)
+ {
+ vec2 samptc = tc + kern[i].z*dlt;
+ 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;
+ }
+ }
+
+ for (int i = 1; i < 4; i++)
+ {
+ vec2 samptc = tc - kern[i].z*dlt;
+ 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 /= defined_weight.xyxx;
+ col.y *= col.y;
+
+ frag_color = col;
#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 awawy which leads to unfun crashes and artifacts.
- vec3 dummy1 = kern[0];
- vec3 dummy2 = kern[3];
+ // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts.
+ vec3 dummy1 = kern[0];
+ vec3 dummy2 = kern[3];
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 58fb01d200..b5677a07ee 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -22,6 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -40,11 +42,7 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
new file mode 100644
index 0000000000..0157d166e0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
@@ -0,0 +1,127 @@
+/**
+ * @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
new file mode 100644
index 0000000000..effb070f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
@@ -0,0 +1,63 @@
+/**
+ * @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 1d8ca04ccd..ae1ac5de7f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsF.glsl
+ * @file class1\deferred\cloudsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,7 +22,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -39,69 +39,93 @@ VARYING vec4 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 vec4 gamma;
+uniform float cloud_scale;
+uniform float cloud_variance;
VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
VARYING vec2 vary_texcoord2;
VARYING vec2 vary_texcoord3;
+VARYING float altitude_blend_factor;
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
+vec3 scaleSoftClip(vec3 light);
- return 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;
-
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
- vec2 uv3 = vary_texcoord2.xy;
- vec2 uv4 = vary_texcoord3.xy;
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy; //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
-
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, 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;
-
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (texture2D(cloud_noise_texture, 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;
-
- // Combine
- vec4 color;
- color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color *= 2.;
-
- /// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,1,0);
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+
+ vec4 cloudColorSun = vary_CloudColorSun;
+ vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ float cloudDensity = vary_CloudDensity;
+ vec2 uv3 = vary_texcoord2.xy;
+ vec2 uv4 = vary_texcoord3.xy;
+
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+
+ 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;
+
+ alpha1 *= altitude_blend_factor;
+ alpha1 = clamp(alpha1, 0.0, 1.0);
+
+ // 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;
+
+ // Combine
+ vec4 color;
+ color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+ color.rgb= max(vec3(0), color.rgb);
+ color.rgb *= 2.0;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ /// 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);
+
+ 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 17f425475c..8e0a001403 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -41,13 +41,16 @@ VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
VARYING vec2 vary_texcoord2;
VARYING vec2 vary_texcoord3;
+VARYING float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
-uniform vec4 ambient;
+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;
@@ -58,128 +61,128 @@ uniform float density_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
uniform float cloud_scale;
+// NOTE: Keep these in sync!
+// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
+// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+// indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl
+// indra\newview\lllegacyatmospherics.cpp
+// indra\newview\llsettingsvo.cpp
void main()
{
-
// World / view / projection
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
+ // Texture coords
+ // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+ vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y); // See: LLSettingsVOSky::applySpecial
+
+ vary_texcoord0.xy -= 0.5;
+ vary_texcoord0.xy /= 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.;
// Get relative position
- vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+ vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
// Set altitude
- if (P.y > 0.)
+ if (rel_pos.y > 0)
{
- P *= (max_y / P.y);
+ rel_pos *= (max_y / rel_pos.y);
}
- else
+ if (rel_pos.y < 0)
{
- P *= (-32000. / P.y);
+ altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
+ rel_pos *= (-32000. / rel_pos.y);
}
// Can normalize then
- vec3 Pn = normalize(P);
- float Plen = length(P);
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 temp1 = vec4(0.);
- vec4 temp2 = vec4(0.);
- vec4 blue_weight;
- vec4 haze_weight;
vec4 sunlight = sunlight_color;
vec4 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 + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
- blue_weight = blue_density / temp1;
- haze_weight = haze_density / temp1;
+ vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+ vec4 blue_weight = blue_density / combined_haze;
+ vec4 haze_weight = haze_density / combined_haze;
- // Compute sunlight from P & lightnorm (for long rays like sky)
- temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
+ // 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);
+ sunlight *= exp(-light_atten * off_axis);
// Distance
- temp2.z = Plen * density_multiplier;
+ float density_dist = rel_pos_len * density_multiplier;
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
// compiler gets confused.
- temp1 = exp(-temp1 * temp2.z);
-
+ combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
- temp2.x = dot(Pn, lightnorm.xyz);
- temp2.x = 1. - temp2.x;
- // temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .001);
+ float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ // 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)
- temp2.x *= glow.x;
+ haze_glow *= glow.x;
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
+ haze_glow = pow(haze_glow, glow.z);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
+ haze_glow *= sun_moon_glow_factor;
+
// Add "minimum anti-solar illumination"
- temp2.x += .25;
+ // 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);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
+ vec4 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 = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
- );
+ vec4 additiveColorBelowCloud =
+ (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
-
- sunlight = sunlight_color;
- temp2.y = max(0., lightnorm.y * 2.);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
+ sunlight = sunlight_color; // SL-14707 reset color -- Clouds are unusually dim in EEP
+ off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
+ sunlight *= exp(-light_atten * off_axis);
// Cloud color out
- vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
+ vary_CloudColorSun = (sunlight * haze_glow) * cloud_color;
vary_CloudColorAmbient = tmpAmbient * cloud_color;
// Attenuate cloud color by atmosphere
- temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
- vary_CloudColorSun *= temp1;
- vary_CloudColorAmbient *= temp1;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
+ 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);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
- // Texture coords
- vary_texcoord0 = texcoord0;
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= 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.;
-
// Combine these to minimize register use
vary_CloudColorAmbient += oHazeColorBelowCloud;
@@ -188,4 +191,3 @@ void main()
// END CLOUDS
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index fef1c5a584..079d8458c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -50,15 +50,6 @@ uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
-float getDepth(vec2 pos_screen)
-{
- float z = texture2DRect(depthMap, pos_screen.xy).r;
- z = z*2.0-1.0;
- vec4 ndc = vec4(0.0, 0.0, z, 1.0);
- vec4 p = inv_proj*ndc;
- return p.z/p.w;
-}
-
float calc_cof(float depth)
{
float sc = (depth-focal_distance)/-depth*blur_constant;
@@ -77,8 +68,12 @@ float calc_cof(float depth)
void main()
{
vec2 tc = vary_fragcoord.xy;
-
- float depth = getDepth(tc);
+
+ float z = texture2DRect(depthMap, tc).r;
+ z = z*2.0-1.0;
+ vec4 ndc = vec4(0.0, 0.0, z, 1.0);
+ vec4 p = inv_proj*ndc;
+ float depth = p.z/p.w;
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
new file mode 100644
index 0000000000..e27bbce094
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -0,0 +1,79 @@
+/**
+ * @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/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index 7930b5d18b..b328ee9483 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -37,11 +39,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index 8525e13333..fc5c86b4d6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -36,11 +38,7 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 37d70a2412..1bb8eb8bd0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -23,6 +23,7 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -37,11 +38,7 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 6befb1bd8b..8319e61242 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -22,6 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
@@ -35,11 +37,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index adc361d7a2..ccd1df84f9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -33,17 +35,13 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
+vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
-
+
vec3 spec;
spec.rgb = vec3(vertex_color.a);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 0ffca8515c..f0522850de 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -44,7 +44,6 @@ void main()
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
- color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
index 115b04797f..5e4f08b017 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
@@ -34,11 +34,8 @@ ATTRIBUTE vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 756e625d07..57420158ca 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file fullbrightF.glsl
+ * @file deferred/fullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,7 +33,7 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-#if !HAS_DIFFUSE_LOOKUP
+#if !defined(HAS_DIFFUSE_LOOKUP)
uniform sampler2D diffuseMap;
#endif
@@ -41,108 +41,22 @@ VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
-
-vec3 fullbrightAtmosTransportDeferred(vec3 light)
-{
- return light;
-}
-
-vec3 fullbrightScaleSoftClipDeferred(vec3 light)
-{
- //soft clip effect:
- return light;
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cl);
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- 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;
-
- 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;
-}
-#endif
-
void main()
{
-#if HAS_DIFFUSE_LOOKUP
+#ifdef HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -158,19 +72,14 @@ void main()
#endif
color.rgb *= vertex_color.rgb;
- color.rgb = srgb_to_linear(color.rgb);
- color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
- color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
-
- color.rgb = linear_to_srgb(color.rgb);
#ifdef WATER_FOG
vec3 pos = vary_position;
- vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
+ vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
color.rgb = fogged.rgb;
color.a = fogged.a;
#else
- color.a = final_alpha;
+ color.a = final_alpha;
#endif
frag_color.rgb = color.rgb;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index b0db9876d3..9fcee04c32 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -23,7 +23,7 @@
* $/LicenseInfo$
*/
-
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,41 +31,75 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-#ifndef diffuseLookup
+#ifndef HAS_DIFFUSE_LOOKUP
uniform sampler2D diffuseMap;
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
+VARYING vec4 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);
+
+// See:
+// class1\deferred\fullbrightShinyF.glsl
+// class1\lighting\lightFullbrightShinyF.glsl
void main()
{
-#if HAS_DIFFUSE_LOOKUP
+#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.xyz/vary_position.w;
+
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ float env_intensity = vertex_color.a;
- color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
-
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+ //color.rgb = srgb_to_linear(color.rgb);
+ color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
+ color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
+
+/*
+ // NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
+ else
+ {
+ vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+ float env_intensity = vertex_color.a;
+ color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
+ }
+*/
color.a = 1.0;
- color.rgb = pow(color.rgb, vec3(1.0/2.2));
+ //color.rgb = linear_to_srgb(color.rgb);
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 34bd8d445a..8f6eb79668 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;
void main()
{
@@ -53,7 +53,7 @@ void main()
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
vec3 ref = reflect(pos.xyz, -norm);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 8e899e3e0f..bdf3546aa5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -35,10 +35,8 @@ ATTRIBUTE vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
#ifdef WATER_FOG
VARYING vec3 vary_position;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index f8fdde43f9..eb6e56e718 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -38,41 +40,7 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
+vec3 linear_to_srgb(vec3 c);
void main()
{
@@ -87,7 +55,6 @@ void main()
vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
col.rgb = linear_to_srgb(col.rgb);
-
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
frag_data[2] = vec4(norm.xy,0,0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
new file mode 100644
index 0000000000..49bfa660f8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
@@ -0,0 +1,30 @@
+/**
+ * @file class1/deferred/indirect.glsl
+ *
+ * $LicenseInfo:firstyear=2018&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 getIndirect(vec3 ambient, vec3 norm, vec3 pos, vec2 pos_screen)
+{
+ return ambient;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index dcf474824d..be1003a7e0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -22,8 +22,8 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-uniform sampler2DRect diffuseMap;
+
+/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,6 +31,7 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform sampler2DRect diffuseMap;
VARYING vec2 vary_fragcoord;
void main()
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 07d28ed4cd..e1f7031af6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -1,72 +1,56 @@
-/**
- * @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$
- */
-
-#define DIFFUSE_ALPHA_MODE_IGNORE 0
-#define DIFFUSE_ALPHA_MODE_BLEND 1
-#define DIFFUSE_ALPHA_MODE_MASK 2
+/**
+* @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;
-uniform float display_gamma;
+uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
+uniform int sun_up_factor;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
+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)
@@ -76,404 +60,115 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-#if HAS_SUN_SHADOW
-
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 shadow_res;
-uniform float shadow_bias;
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
#endif
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
// Inputs
uniform vec4 morphFactor;
uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-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 env_mat;
-uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
VARYING vec2 vary_fragcoord;
VARYING vec3 vary_position;
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
+uniform mat4 proj_mat;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- 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;
-
- 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;
-}
-#endif
-
-vec3 calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return vec3(a,a,a);
-}
-
-
-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)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = length(lv);
-
- float da = 1.0;
-
- vec3 col = vec3(0,0,0);
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist = d/la;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
-
- float lit = max(da * dist_atten, 0.0);
-
- col = light_col*lit*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;
- 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);
- //col += spec.rgb;
- }
- }
- }
-
- return max(col, vec3(0.0,0.0,0.0));
-
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
-}
-
-#ifndef WATER_FOG
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-#endif
-
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
+float getAmbientClamp();
-void setAmblitColor(vec3 v)
+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)
{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * 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);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
- vec3 ones = vec3(1.0f, 1.0f, 1.0f);
-
- light = ones - clamp(light, zeroes, ones);
- light = ones - pow(light, gamma.xxx);
-
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz - v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ dist /= la;
+
+ if (dist > 0.0 && 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
@@ -484,13 +179,13 @@ out vec4 frag_data[3];
#endif
#endif
-uniform sampler2D diffuseMap;
+uniform sampler2D diffuseMap; //always in sRGB space
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
uniform sampler2D bumpMap;
#endif
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
uniform sampler2D specularMap;
VARYING vec2 vary_texcoord2;
@@ -503,7 +198,7 @@ uniform vec4 specular_color; // specular color RGB and specular exponent (gloss
uniform float minimum_alpha;
#endif
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
VARYING vec3 vary_mat2;
@@ -515,33 +210,23 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
-vec3 decode_normal (vec2 enc)
+void main()
{
- 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;
-}
+ vec2 pos_screen = vary_texcoord0.xy;
-void main()
-{
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
- if (diffcol.a < minimum_alpha)
- {
- discard;
- }
+
+ // 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)
@@ -549,14 +234,14 @@ void main()
diffcol.rgb = srgb_to_linear(diffcol.rgb);
#endif
-#if HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
+#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);
+ vec4 spec = vec4(specular_color.rgb, 1.0);
#endif
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
norm.xyz = norm.xyz * 2 - 1;
@@ -569,220 +254,192 @@ void main()
vec3 tnorm = vary_normal;
#endif
- norm.xyz = tnorm;
- norm.xyz = normalize(norm.xyz);
+ norm.xyz = normalize(tnorm.xyz);
- vec2 abnormal = encode_normal(norm.xyz);
- norm.xyz = decode_normal(abnormal.xy);
+ vec2 abnormal = encode_normal(norm.xyz);
+
+ vec4 final_color = diffcol;
- 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;
-#if HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
+ 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 RGBA
- vec3 pos = vary_position;
-
-#if HAS_SUN_SHADOW
- float shadow = 0.0;
-
- vec4 spos = vec4(pos,1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-#else
- float shadow = 1.0;
+
+ //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;
+ 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));
- vec3 col = vec3(0.0f,0.0f,0.0f);
+ //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);
- float bloom = 0.0;
- calcAtmospherics(pos.xyz, 1.0);
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ color = amblit;
- float da =dot(norm.xyz, sun_dir.xyz);
+ //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);
- float final_da = da;
- final_da = min(final_da, shadow);
- //final_da = max(final_da, diffuse.a);
- final_da = max(final_da, 0.0f);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
+ vec3 sun_contrib = min(da, shadow) * sunlit;
+
+ color *= ambient;
- col.rgb = atmosAmbient(col);
-
- float ambient = min(abs(da), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
+ color += sun_contrib;
- col.rgb *= ambient;
+ color *= gamma_diff.rgb;
- col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
+ float glare = 0.0;
- col.rgb *= gamma_diff.rgb;
-
+ 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.
- float glare = 0.0;
+ vec3 npos = -normalize(pos.xyz);
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*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;
+ //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;
- glare = max(spec_contrib.r, spec_contrib.g);
- glare = max(glare, spec_contrib.b);
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
- col += spec_contrib;
- }
+ 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);
- col = mix(col.rgb, diffcol.rgb, diffuse.a);
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
- if (envIntensity > 0.0)
- {
- //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+ glare = max(spec_contrib.r, spec_contrib.g);
+ glare = max(glare, spec_contrib.b);
- col = mix(col.rgb, refcol,
- envIntensity);
+ color += spec_contrib;
+ }
- float cur_glare = max(refcol.r, refcol.g);
- cur_glare = max(cur_glare, refcol.b);
- cur_glare *= envIntensity*4.0;
- glare += cur_glare;
- }
+ color = mix(color.rgb, diffcol.rgb, diffuse.a);
- //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ if (envIntensity > 0.0)
+ {
+ //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
- col = atmosLighting(col);
- col = scaleSoftClip(col);
+ vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
- //convert to linear space before adding local lights
- col = srgb_to_linear(col);
+ color = mix(color, reflected_color, envIntensity);
- vec3 npos = normalize(-pos.xyz);
-
- vec3 light = vec3(0,0,0);
+ 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;
+ }
- #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);
+ color = atmosFragLighting(color, additive, atten);
+ color = scaleSoftClipFrag(color);
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
+ //convert to linear before adding local lights
+ color = srgb_to_linear(color);
- col.rgb += light.rgb;
+ vec3 npos = normalize(-pos.xyz);
- glare = min(glare, 1.0);
- float al = max(diffcol.a,glare)*vertex_color.a;
+ vec3 light = vec3(0, 0, 0);
+
+ final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035
- //convert to gamma space for display on screen
- col.rgb = linear_to_srgb(col.rgb);
+#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 = applyWaterFogDeferred(pos, vec4(col.rgb, al));
- col.rgb = temp.rgb;
- al = temp.a;
+ vec4 temp = applyWaterFogView(pos, vec4(color, al));
+ color = temp.rgb;
+ al = temp.a;
#endif
- frag_color.rgb = col.rgb;
- frag_color.a = al;
+ frag_color = vec4(color, al);
-#else
- frag_data[0] = final_color;
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+#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.
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 393d1e69da..7e29ada205 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -28,7 +28,7 @@
#define DIFFUSE_ALPHA_MODE_MASK 2
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-#if HAS_SKIN
+#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
mat4 getObjectSkinnedTransform();
@@ -39,7 +39,7 @@ uniform mat4 modelview_projection_matrix;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-#if !HAS_SKIN
+#if !defined(HAS_SKIN)
uniform mat4 modelview_matrix;
#endif
@@ -55,7 +55,7 @@ ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
ATTRIBUTE vec4 tangent;
ATTRIBUTE vec2 texcoord1;
@@ -68,7 +68,7 @@ VARYING vec2 vary_texcoord1;
VARYING vec3 vary_normal;
#endif
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
ATTRIBUTE vec2 texcoord2;
VARYING vec2 vary_texcoord2;
#endif
@@ -78,7 +78,7 @@ VARYING vec2 vary_texcoord0;
void main()
{
-#if HAS_SKIN
+#ifdef HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
@@ -99,17 +99,17 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
#endif
-#if HAS_SPECULAR_MAP
+#ifdef HAS_SPECULAR_MAP
vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
#endif
-#if HAS_SKIN
+#ifdef HAS_SKIN
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
vec3 b = cross(n, t)*tangent.w;
@@ -121,7 +121,7 @@ vary_normal = n;
#endif //HAS_NORMAL_MAP
#else //HAS_SKIN
vec3 n = normalize(normal_matrix * normal);
-#if HAS_NORMAL_MAP
+#ifdef HAS_NORMAL_MAP
vec3 t = normalize(normal_matrix * tangent.xyz);
vec3 b = cross(n,t)*tangent.w;
//vec3 t = cross(b,n) * binormal.w;
@@ -137,7 +137,7 @@ vary_normal = n;
vertex_color = diffuse_color;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-#if !HAS_SKIN
+#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/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
new file mode 100644
index 0000000000..35068899ee
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @file class1\deferred\moonF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, 2020 Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform vec4 color;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform vec3 moon_dir;
+uniform float moon_brightness;
+uniform sampler2D diffuseMap;
+
+VARYING vec2 vary_texcoord0;
+
+vec3 srgb_to_linear(vec3 c);
+
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
+
+void main()
+{
+ // Restore Pre-EEP alpha fade moon near horizon
+ float fade = 1.0;
+ if( moon_dir.z > 0 )
+ fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
+
+ vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+// c.rgb = srgb_to_linear(c.rgb);
+ c.rgb *= moonlight_color.rgb;
+ c.rgb *= moon_brightness;
+
+ c.rgb *= fade;
+ c.a *= fade;
+
+ c.rgb = scaleSoftClip(c.rgb);
+
+ frag_data[0] = vec4(c.rgb, c.a);
+ frag_data[1] = vec4(0.0);
+ frag_data[2] = vec4(0.0f);
+
+ gl_FragDepth = 0.999985f;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
new file mode 100644
index 0000000000..c4922afd7d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -0,0 +1,44 @@
+/**
+ * @file class1\deferred\moonV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 2020 Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz, 1.0);
+ vec4 pos = (modelview_matrix * vert);
+
+ gl_Position = modelview_projection_matrix*vert;
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 9974f8f31b..09c47165dd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -1,24 +1,24 @@
-/**
- * @file multiPointLightF.glsl
+/**
+ * @file class1/deferred/multiPointLightF.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$
*/
@@ -36,139 +36,110 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-
+uniform samplerCube environmentMap;
+uniform sampler2D noiseMap;
+uniform sampler2D lightFunc;
-uniform vec3 env_mat[3];
+uniform vec3 env_mat[3];
uniform float sun_wash;
+uniform int light_count;
+uniform vec4 light[LIGHT_COUNT];
+uniform vec4 light_col[LIGHT_COUNT];
-uniform int light_count;
-
-uniform vec4 light[LIGHT_COUNT];
-uniform vec4 light_col[LIGHT_COUNT];
-
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
+uniform vec2 screen_res;
uniform float far_z;
+uniform mat4 inv_proj;
-uniform mat4 inv_proj;
+VARYING vec4 vary_fragcoord;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
-vec3 decode_normal (vec2 enc)
+void main()
{
- 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;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
-}
+#if defined(LOCAL_LIGHT_KILL)
+ discard; // Bail immediately
+#endif
-void main()
-{
- vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
- vec3 pos = getPosition(frag.xy).xyz;
- if (pos.z < far_z)
- {
- discard;
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = decode_normal(norm.xy); // unpack norm
- norm = normalize(norm);
- vec4 spec = texture2DRect(specularRect, frag.xy);
- vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- vec3 out_col = vec3(0,0,0);
- vec3 npos = normalize(-pos);
-
- // 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 da = dot(norm, lv);
- if (da > 0.0)
- {
- lv = normalize(lv);
- da = dot(norm, lv);
-
- float fa = light_col[i].a+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- dist_atten *= noise;
-
- float lit = da * dist_atten;
-
- vec3 col = light_col[i].rgb*lit*diff;
-
- //vec3 col = vec3(dist2, light_col[i].a, lit);
-
- if (spec.a > 0.0)
- {
- lit = 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));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += lit*scol*light_col[i].rgb*spec.rgb;
- //col += spec.rgb;
- }
- }
-
- out_col += col;
- }
- }
- }
-
-
- frag_color.rgb = out_col;
- frag_color.a = 0.0;
+ vec3 out_col = vec3(0, 0, 0);
+ vec2 frag = (vary_fragcoord.xy * 0.5 + 0.5) * screen_res;
+ vec3 pos = getPosition(frag.xy).xyz;
+ if (pos.z < far_z)
+ {
+ discard;
+ }
+
+ vec3 norm = getNorm(frag.xy);
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+ vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
+
+ float noise = texture2D(noiseMap, frag.xy / 128.0).b;
+ vec3 npos = normalize(-pos);
+
+ // 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 da = dot(norm, lv);
+ if (da > 0.0)
+ {
+ lv = normalize(lv);
+ da = dot(norm, lv);
+
+ float fa = light_col[i].a + 1.0;
+ float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 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;
+
+ dist_atten *= noise;
+
+ float lit = da * dist_atten;
+
+ vec3 col = light_col[i].rgb * lit * diff;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(da * 6.0, 1.0) * dist_atten;
+ 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)
+ {
+ float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * da);
+ col += lit * scol * light_col[i].rgb * spec.rgb;
+ }
+ }
+
+ out_col += col;
+ }
+ }
+ }
+
+ frag_color.rgb = out_col;
+ frag_color.a = 0.0;
#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 awawy 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];
+ // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage
+ // awawy 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/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 3a3e871ade..ec3fb9c543 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -30,14 +30,14 @@
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-/*[EXTRA_CODE_HERE]*/
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -71,60 +71,8 @@ VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
@@ -178,22 +126,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -208,12 +149,9 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
+ float envIntensity = texture2DRect(normalMap, frag.xy).z;
+ vec3 norm = getNorm(frag.xy);
- norm = decode_normal(norm.xy);
-
- norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -225,25 +163,29 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
+
if (dist_atten <= 0.0)
{
discard;
}
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ dist_atten *= noise;
+
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+
vec3 dlit = vec3(0, 0, 0);
- 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 &&
@@ -262,7 +204,7 @@ void main()
dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
+ lit = da * dist_atten;
col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
@@ -304,7 +246,7 @@ void main()
col += dlit*scol*spec.rgb;
//col += spec.rgb;
}
- }
+ }
if (envIntensity > 0.0)
{
@@ -334,7 +276,9 @@ void main()
}
}
}
-
+#endif
+
+ //output linear, sum of lights will be gamma corrected later
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index aba4a01754..18616a9bb3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -56,103 +56,77 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = (pos_screen.xy-viewport.xy)*2.0;
- sc /= viewport.zw;
- sc -= vec2(1.0,1.0);
- 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 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
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;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = decode_normal(norm.xy); // unpack norm
- float da = dot(norm, lv);
- if (da < 0.0)
- {
- discard;
- }
-
- norm = normalize(norm);
- lv = normalize(lv);
- da = dot(norm, lv);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
-
- vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
- float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- float lit = da * dist_atten * noise;
-
- col = color.rgb*lit*col;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
- if (spec.a > 0.0)
- {
- lit = min(da*6.0, 1.0) * dist_atten;
-
- vec3 npos = -normalize(pos);
- 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)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += lit*scol*color.rgb*spec.rgb;
- }
- }
-
- if (dot(col, col) <= 0.0)
- {
- discard;
- }
-
- frag_color.rgb = col;
- frag_color.a = 0.0;
+ 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;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
+ {
+ discard;
+ }
+
+ vec3 norm = getNorm(frag.xy);
+
+ float da = dot(norm, lv);
+ if (da < 0.0)
+ {
+ discard;
+ }
+
+ lv = normalize(lv);
+ da = dot(norm, lv);
+
+ float noise = texture2D(noiseMap, frag.xy/128.0).b;
+
+ vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
+
+ float fa = falloff+1.0;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ float lit = da * dist_atten * noise;
+
+ col = color.rgb*lit*col;
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+ if (spec.a > 0.0)
+ {
+ lit = min(da*6.0, 1.0) * dist_atten;
+
+ vec3 npos = -normalize(pos);
+ 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)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*color.rgb*spec.rgb;
+ }
+ }
+
+ if (dot(col, col) <= 0.0)
+ {
+ discard;
+ }
+
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index a5625fbc16..3da8531442 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file pointLightF.glsl
+ * @file pointLightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 6669947d1b..cd37a34e0d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -37,33 +37,16 @@ uniform sampler2DRect diffuseRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
-
uniform float display_gamma;
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
+vec3 linear_to_srgb(vec3 cl);
void main()
{
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- diff.rgb = linear_to_srgb(diff.rgb);
- frag_color = diff;
+ //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);
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 018ced4cad..cf994d3547 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -47,18 +49,7 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
new file mode 100644
index 0000000000..44f2a73e1f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
@@ -0,0 +1,55 @@
+/**
+ * @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;
+
+void main()
+{
+ float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+
+ frag_color = vec4(alpha, alpha, alpha, 1);
+
+#if !defined(DEPTH_CLAMP)
+ gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
new file mode 100644
index 0000000000..f45c343066
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @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 pos_w;
+
+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);
+ 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/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index 91a96977f0..9b8df0a5a4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -31,19 +33,25 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
+VARYING vec4 post_pos;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+uniform float minimum_alpha;
void main()
{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+ float alpha = diffuseLookup(vary_texcoord0.xy).a;
+
+ // mask cutoff 0 -> no shadow SL-11051
+ if (minimum_alpha == 0)
+ {
+ discard;
+ }
+
+#if !defined(IS_FULLBRIGHT)
+ alpha *= vertex_color.a;
+#endif
if (alpha < 0.05) // treat as totally transparent
{
@@ -52,7 +60,7 @@ void main()
if (alpha < 0.88) // treat as semi-transparent
{
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+ if (fract(0.5*floor(target_pos_x / post_pos.w )) < 0.25)
{
discard;
}
@@ -60,7 +68,7 @@ void main()
frag_color = vec4(1,1,1,1);
-#if !DEPTH_CLAMP
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.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/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index 11411a605c..b6a0f0b165 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -31,12 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-#if !DEPTH_CLAMP
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
+VARYING vec4 post_pos;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -50,11 +45,9 @@ void main()
vec4 pos = modelview_projection_matrix * pre_pos;
target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
- pos_w = pos.w;
+ post_pos = pos;
-#if !DEPTH_CLAMP
- pos_zd2 = pos.z * 0.5;
-
+#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
index ef153dfc5b..0e74d2eb8a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -27,7 +27,7 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-#if !DEPTH_CLAMP
+#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
@@ -40,7 +40,7 @@ void main()
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-#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/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 3d1b182875..1ea96918bb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -23,21 +23,21 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-#if !DEPTH_CLAMP
VARYING vec4 post_pos;
-#endif
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/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
new file mode 100644
index 0000000000..4134220306
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
@@ -0,0 +1,221 @@
+/**
+ * @file class1/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 sampler2DRect normalMap;
+uniform sampler2DRect depthMap;
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
+uniform sampler2DShadow shadowMap4;
+uniform sampler2DShadow 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 shadow_offset;
+uniform float spot_shadow_bias;
+uniform float spot_shadow_offset;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+uniform int sun_up_factor;
+
+float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul, vec2 pos_screen, vec3 light_dir)
+{
+ float offset = shadow_bias * bias_mul;
+ stc.xyz /= stc.w;
+ stc.z += offset * 2.0;
+ stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs * 4.0;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ return clamp(shadow * 0.125, 0.0, 1.0);
+}
+
+float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen)
+{
+ stc.xyz /= stc.w;
+ stc.z += spot_shadow_bias * bias_scale;
+ stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ vec2 off = 1.0/proj_shadow_res;
+ off.y *= 1.5;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+ return shadow*0.2;
+}
+
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
+{
+ float shadow = 0.0f;
+ vec3 light_dir = normalize((sun_up_factor == 1) ? sun_dir : moon_dir);
+
+ float dp_directional_light = max(0.0, dot(norm.xyz, light_dir));
+ dp_directional_light = clamp(dp_directional_light, 0.0, 1.0);
+
+ vec3 shadow_pos = pos.xyz;
+
+ vec3 offset = light_dir.xyz * (1.0 - dp_directional_light);
+
+ shadow_pos += offset * shadow_offset * 2.0;
+
+ vec4 spos = vec4(shadow_pos.xyz, 1.0);
+
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap3, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap2, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap1, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+ //w = clamp(w, 0.0, 1.0);
+ float contrib = pcfShadow(shadowMap0, norm, lpos, 1.0, pos_screen, light_dir)*w;
+ //if (contrib > 0)
+ {
+ shadow += contrib;
+ weight += w;
+ }
+ }
+
+ shadow /= weight;
+ }
+ else
+ {
+ return 1.0f; // lit beyond the far split...
+ }
+ //shadow = min(dp_directional_light,shadow);
+ return shadow;
+}
+
+float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
+{
+ float shadow = 0.0f;
+ pos += norm * spot_shadow_offset;
+
+ vec4 spos = vec4(pos,1.0);
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ {
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+
+ if (index == 0)
+ {
+ lpos = shadow_matrix[4]*spos;
+ shadow += pcfSpotShadow(shadowMap4, lpos, 0.8, spos.xy)*w;
+ }
+ else
+ {
+ lpos = shadow_matrix[5]*spos;
+ shadow += pcfSpotShadow(shadowMap5, lpos, 0.8, spos.xy)*w;
+ }
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0f;
+ }
+ return shadow;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index cc77a4cea0..72bd0f0f34 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -27,20 +27,19 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-#if !DEPTH_CLAMP
VARYING vec4 post_pos;
-#endif
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-#if !DEPTH_CLAMP
post_pos = pos;
+#if !defined(DEPTH_CLAMP)
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/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 22f4729e2e..331249dc33 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyF.glsl
+ * @file class1/deferred/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -35,32 +37,28 @@ out vec4 frag_data[3];
VARYING vec4 vary_HazeColor;
-uniform sampler2D cloud_noise_texture;
-uniform vec4 gamma;
-
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
+vec3 scaleSoftClip(vec3 light);
+vec3 srgb_to_linear(vec3 c);
void main()
{
- // Potential Fill-rate optimization. Add cloud calculation
- // back in and output alpha of 0 (so that alpha culling kills
- // the fragment) if the sky wouldn't show up because the clouds
- // are fully opaque.
+ // Potential Fill-rate optimization. Add cloud calculation
+ // back in and output alpha of 0 (so that alpha culling kills
+ // the fragment) if the sky wouldn't show up because the clouds
+ // are fully opaque.
+
+ vec4 color;
+ color = vary_HazeColor;
+
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
- vec4 color;
- color = vary_HazeColor;
- color *= 2.;
+ /// 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
- /// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0.5,0.5,0.0,1.0); //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 7c02d31d43..28a1faf24f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -1,24 +1,24 @@
-/**
+/**
* @file WLSkyV.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$
*/
@@ -37,121 +37,117 @@ VARYING vec4 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+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 vec4 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
+// indra\newview\lllegacyatmospherics.cpp
void main()
{
+ // World / view / projection
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Get relative position
- vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
- //vec3 P = position.xyz + vec3(0,50,0);
-
- // Set altitude
- if (P.y > 0.)
- {
- P *= (max_y / P.y);
- }
- else
- {
- P *= (-32000. / P.y);
- }
-
- // Can normalize then
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- // Initialize temp variables
- vec4 temp1 = vec4(0.);
- vec4 temp2 = vec4(0.);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
-
- // Calculate relative weights
- temp1 = blue_density + haze_density;
- blue_weight = blue_density / temp1;
- haze_weight = haze_density / temp1;
-
- // Compute sunlight from P & lightnorm (for long rays like sky)
- temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // Distance
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z);
-
-
- // Compute haze glow
- temp2.x = dot(Pn, lightnorm.xyz);
- temp2.x = 1. - temp2.x;
- // temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- temp2.x += .25;
-
-
- // Haze color above cloud
- vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
- );
-
-
- // Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
-
- // Haze color below cloud
- vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
- );
-
- // Final atmosphere additive
- vary_HazeColor *= (1. - temp1);
-
- // Attenuate cloud color by atmosphere
- temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
-
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1));
-
- // won't compile on mac without this being set
- //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-}
+ gl_Position = pos;
+
+ // Get relative position
+ vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ // Adj position vector to clamp altitude
+ if (rel_pos.y > 0)
+ {
+ rel_pos *= (max_y / rel_pos.y);
+ }
+ if (rel_pos.y < 0)
+ {
+ rel_pos *= (-32000. / rel_pos.y);
+ }
+
+ // Can normalize then
+ vec3 rel_pos_norm = normalize(rel_pos);
+
+ float rel_pos_len = length(rel_pos);
+
+ // Initialize temp variables
+ vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec4 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);
+
+ // 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;
+
+ // 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);
+ sunlight *= exp(-light_atten * off_axis);
+ // Distance
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist);
+
+ // Compute haze glow
+ float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ // 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"
+ // 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 =
+ (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;
+
+ // Dim sunlight by cloud shadow percentage
+ sunlight *= max(0.0, (1. - cloud_shadow));
+
+ // Haze color below cloud
+ vec4 additiveColorBelowCloud =
+ (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+
+ // Attenuate cloud color by atmosphere
+ combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
+
+ // At horizon, blend high altitude sky color towards the darker color below the clouds
+ color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
+
+ // Haze color above cloud
+ vary_HazeColor = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 03bdb754b5..7f2c603f87 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file softenLightF.glsl
+ * @file class1/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,442 +36,135 @@ out vec4 frag_color;
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
-uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-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 global_gamma;
-uniform float scene_light_strength;
uniform mat3 env_mat;
-uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+float getAmbientClamp();
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- 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;
-
- 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 applyWaterFogView(vec3 pos, vec4 color);
#endif
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * 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);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
-
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-
-
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
-
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
-
void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPosition_d(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = decode_normal(norm.xy); // unpack norm
-
- float da = dot(norm.xyz, sun_dir.xyz);
-
- float final_da = max(0.0,da);
- final_da = min(final_da, 1.0f);
- final_da = pow(final_da, 1.0/1.3);
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
-
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
-
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- vec3 col;
- float bloom = 0.0;
- {
- calcAtmospherics(pos.xyz, 1.0);
-
- col = atmosAmbient(vec3(0));
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb *= ambient;
-
- col += atmosAffectDirectionalLight(final_da);
-
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(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;
- col += spec_contrib;
- }
-
-
- col = mix(col.rgb, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
-
- col = mix(col.rgb, refcol,
- envIntensity);
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- }
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
-
- col = srgb_to_linear(col);
-
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
-
- frag_color.rgb = col.rgb;
- frag_color.a = bloom;
+ 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);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ float light_gamma = 1.0/1.3;
+ da = pow(da, light_gamma);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
+
+ //convert to gamma space
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
+
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+ vec3 color = vec3(0);
+ float bloom = 0.0;
+ {
+ float ambocc = 1.0; // no AO...
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, false);
+
+ color.rgb = amblit;
+
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
+
+ color.rgb *= ambient;
+
+ vec3 sun_contrib = da * sunlit;
+
+ color.rgb += sun_contrib;
+
+ color.rgb *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ float sa = dot(refnormpersp, light_dir.xyz);
+ vec3 dumbshiny = sunlit * (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;
+ color.rgb += spec_contrib;
+ }
+
+ color.rgb = mix(color.rgb, diffuse.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.rgb, reflected_color, envIntensity);
+ }
+
+ if (norm.w < 0.5)
+ {
+ color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
+ color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
+ }
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogView(pos.xyz,vec4(color, bloom));
+ color = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ }
+
+// 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...
+
+ frag_color.rgb = srgb_to_linear(color.rgb);
+ frag_color.a = bloom;
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
index b59fcbe017..8891315e15 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file softenLightF.glsl
+ * @file softenLightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -29,12 +29,17 @@ ATTRIBUTE vec3 position;
uniform vec2 screen_res;
+void setAtmosAttenuation(vec3 c);
+void setAdditiveColor(vec3 c);
+
VARYING vec2 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;
+ //transform vertex
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = pos;
+ // appease OSX GLSL compiler/linker by touching all the varyings we said we would
+ setAtmosAttenuation(vec3(1));
+ setAdditiveColor(vec3(0));
+ vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index f1aec315cc..694b19cdfb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -70,64 +70,8 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
@@ -152,7 +96,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -170,7 +114,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -181,22 +125,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -210,12 +147,10 @@ void main()
{
discard;
}
-
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
- norm = decode_normal(norm.xy);
-
+ norm = getNorm(frag.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -241,13 +176,11 @@ void main()
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
-
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+ //light shaders output linear and are gamma corrected later in postDeferredGammaCorrectF.glsl
+ diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
-
+ vec4 spec = texture2DRect(specularRect, frag.xy);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 dlit = vec3(0, 0, 0);
@@ -284,7 +217,6 @@ void main()
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
}
-
if (spec.a > 0.0)
{
@@ -311,7 +243,6 @@ void main()
}
}
-
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -340,7 +271,9 @@ void main()
}
}
}
-
+#endif
+
+ //col.r = 1.0;
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index 821058804c..bac79a9fdc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -31,14 +33,35 @@ out vec4 frag_data[3];
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+VARYING vec2 screenpos;
uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor;
+uniform float custom_alpha;
+uniform float time;
+
+float twinkle(){
+ float d = fract(screenpos.x + screenpos.y);
+ return abs(d);
+}
void main()
{
- vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy);
-
- frag_data[0] = col;
- frag_data[1] = vec4(0,0,0,0);
- frag_data[2] = vec4(0,0,1,0);
+ vec4 col_a = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col_b = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = mix(col_b, col_a, blend_factor);
+ col.rgb *= vertex_color.rgb;
+
+ float factor = smoothstep(0.0f, 0.9f, custom_alpha);
+
+ col.a = (col.a * factor) * 32.0f;
+ col.a *= twinkle();
+
+ frag_data[0] = col;
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+
+ gl_FragDepth = 0.99995f;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index 8bc5b06379..bb2a2ee72b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
@@ -25,6 +25,7 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
+uniform float time;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
@@ -32,11 +33,20 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+VARYING vec2 screenpos;
void main()
{
//transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * vec4(position, 1.0);
+
+// bias z to fix SL-9806 and get stars to depth test against clouds
+ pos.z += 0.001f;
+
+ gl_Position = pos;
+
+ float t = mod(time, 1.25f);
+ screenpos = position.xy * vec2(t, t);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
new file mode 100644
index 0000000000..b2fa5d8a25
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -0,0 +1,64 @@
+/**
+ * @file sunDiscF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+vec3 srgb_to_linear(vec3 c);
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between sunDisc A/B
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void main()
+{
+ vec4 sunDiscA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(sunDiscA, sunDiscB, blend_factor);
+
+ //c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+
+ // SL-9806 stars poke through
+ //c.a *= sun_fade;
+
+ frag_data[0] = c;
+ frag_data[1] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+
+ gl_FragDepth = 0.999988f;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
new file mode 100644
index 0000000000..0d117c6bc7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
@@ -0,0 +1,52 @@
+/**
+ * @file sunDiscV.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_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec3 offset = vec3(0, 0, 50);
+ vec4 vert = vec4(position.xyz - offset, 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
+
+ gl_Position = pos;
+
+ calcAtmospherics(pos.xyz);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 930255729b..15f141cbe5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -35,103 +35,16 @@ out vec4 frag_color;
//class 1 -- no shadow, SSAO only
-uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform sampler2D noiseMap;
-
// Inputs
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- float ret = 1.0;
-
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- int points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- points = points + int(diff.z > -1.0);
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-
- ret = (1.0 - (float(points != 0) * angle_hidden));
-
- return min(ret, 1.0);
-}
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
void main()
{
@@ -139,13 +52,11 @@ void main()
//try doing an unproject here
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy);
-
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
+
frag_color[0] = 1.0;
- frag_color[1] = calcAmbientOcclusion(pos, norm);
+ frag_color[1] = calcAmbientOcclusion(pos, norm, pos_screen);
frag_color[2] = 1.0;
frag_color[3] = 1.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 52a429465f..6b6eed9db8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainF.glsl
+ * @file class1\deferred\terrainF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -35,33 +37,32 @@ uniform sampler2D detail_2;
uniform sampler2D detail_3;
uniform sampler2D alpha_ramp;
+VARYING vec3 pos;
VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
- /// Note: This should duplicate the blending functionality currently used for the terrain rendering.
-
- vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
+ /// Note: This should duplicate the blending functionality currently used for the terrain rendering.
+
+ vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
+ vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
+ vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
+ vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
- float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
- float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
- float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- frag_data[0] = vec4(outColor.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);
+ float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
+ float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
+ float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
+ vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
+
+ outColor.a = 0.0; // yes, downstream atmospherics
+
+ 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);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index 5effee4e4e..f42cb6ff6d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainV.glsl
+ * @file class1\environment\terrainV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,8 +33,8 @@ ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec2 texcoord1;
+VARYING vec3 pos;
VARYING vec3 vary_normal;
-
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
@@ -43,31 +43,35 @@ uniform vec4 object_plane_t;
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
{
- vec4 tcoord;
-
- tcoord.x = dot(vpos, tp0);
- tcoord.y = dot(vpos, tp1);
- tcoord.z = tc.z;
- tcoord.w = tc.w;
-
- tcoord = mat * tcoord;
-
- return tcoord;
+ vec4 tcoord;
+
+ tcoord.x = dot(vpos, tp0);
+ tcoord.y = dot(vpos, tp1);
+ tcoord.z = tc.z;
+ tcoord.w = tc.w;
+
+ tcoord = mat * tcoord;
+
+ return tcoord;
}
void main()
{
- //transform vertex
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- vary_normal = normalize(normal_matrix * normal);
-
- // Transform and pass tex coords
- vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
- vec4 t = vec4(texcoord1,0,1);
-
- vary_texcoord0.zw = t.xy;
- vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
- vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 t_pos = modelview_projection_matrix * pre_pos;
+
+ gl_Position = t_pos;
+ pos = t_pos.xyz;
+
+ vary_normal = normalize(normal_matrix * normal);
+
+ // Transform and pass tex coords
+ vary_texcoord0.xy = texgen_object(vec4(position, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
+
+ vec4 t = vec4(texcoord1,0,1);
+
+ vary_texcoord0.zw = t.xy;
+ vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 808750496f..89e354558a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -37,11 +39,7 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
+vec2 encode_normal(vec3 n);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
index d4d2f5f571..e34d75ba1d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
index 78f841c733..9a5debb3c1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -56,84 +58,7 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-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 vec4(1.0, 0.0, 1.0, 1.0);
- return color * D + kc * L;
- //depth /= 10.0;
- //return vec4(depth,depth,depth,0.0);
-}
+vec2 encode_normal(vec3 n);
void main()
{
@@ -151,7 +76,7 @@ void main()
vec4 fb = texture2D(screenTex, distort);
- frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
+ 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
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, env intens, 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 37dcd3ad34..a157e9c017 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterF.glsl
+ * @file class1/deferred/waterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -37,17 +37,10 @@ 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 sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2D noiseMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-
uniform float sunAngle;
uniform float sunAngle2;
uniform vec3 lightDir;
@@ -62,6 +55,7 @@ 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;
@@ -69,111 +63,89 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
+vec2 encode_normal(vec3 n);
+vec3 scaleSoftClip(vec3 l);
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
-vec2 encode_normal(vec3 n)
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
+ 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 = 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;
- //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;
+ 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
+
+ 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
@@ -186,19 +158,27 @@ void main()
//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.99999);
+ 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] = vec4(color.rgb, color); // diffuse
- frag_data[1] = vec4(0); // speccolor, spec
- frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
+
+ //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
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index 9734acf005..8863869e44 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
@@ -31,8 +31,8 @@ ATTRIBUTE vec3 position;
void calcAtmospherics(vec3 inPositionEye);
-uniform vec2 d1;
-uniform vec2 d2;
+uniform vec2 waveDir1;
+uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
@@ -88,10 +88,10 @@ void main()
calcAtmospherics(pos.xyz);
//pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
+ vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * 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;
+ littleWave.xy = (v.xy) * vec2(0.45, 0.9) + waveDir2 * time * 0.13;
+ littleWave.zw = (v.xy) * vec2(0.1, 0.2) + waveDir1 * time * 0.1;
view.w = bigWave.y;
refCoord.w = bigWave.x;
diff --git a/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
new file mode 100644
index 0000000000..6cd2445522
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/encodeNormF.glsl
@@ -0,0 +1,34 @@
+/**
+ * @file encodeNormF.glsl
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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$
+ */
+
+// Lambert Azimuthal Equal-Area projection
+// See: https://aras-p.info/texts/CompactNormalStorage.html
+// Also see: A_bit_more_deferred_-_CryEngine3.ppt
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
index 6cc1e6e798..4a8b892c3a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
@@ -1,5 +1,5 @@
/**
- * @file srgb.glsl
+ * @file srgbF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,14 +27,18 @@ vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
-
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
}
vec3 linear_to_srgb(vec3 cl)
@@ -42,13 +46,39 @@ vec3 linear_to_srgb(vec3 cl)
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
-
bvec3 lt = lessThan(cl,vec3(0.0031308));
+#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
- return result;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec3 ColorFromRadiance(vec3 radiance)
+{
+ return vec3(1.0) - exp(-radiance * 0.0001);
}
+vec3 rgb2hsv(vec3 c)
+{
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
+
+ float d = q.x - min(q.w, q.y);
+ float e = 1.0e-10;
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
index 668a710c04..6b68ed4169 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainF.glsl
+ * @file class1\environment\terrainF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
index d09c5f9247..ef27848d37 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainV.glsl
+ * @file class1\environment\terrainV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -35,6 +35,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec4 diffuse_color;
VARYING vec4 vertex_color;
VARYING vec4 vary_texcoord0;
@@ -42,7 +43,7 @@ VARYING vec4 vary_texcoord1;
void calcAtmospherics(vec3 inPositionEye);
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
{
@@ -71,7 +72,7 @@ void main()
/// Potentially better without it for water.
pos /= pos.w;
- vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0));
+ vec4 color = calcLighting(pos.xyz, norm, /*diffuse_color*/vec4(1));
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
index a956562396..e53bb46177 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file terrainWaterF.glsl
+ * @file class1\environment\terrainWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -64,4 +64,3 @@ void main()
outColor = applyWaterFog(outColor);
frag_color = outColor;
}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
new file mode 100644
index 0000000000..a075cfeef2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
@@ -0,0 +1,84 @@
+/**
+ * @file class1\environment\terrainV.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 mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+uniform vec4 object_plane_t;
+uniform vec4 object_plane_s;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec4 diffuse_color;
+
+VARYING vec4 vertex_color;
+VARYING vec4 vary_texcoord0;
+VARYING vec4 vary_texcoord1;
+
+void calcAtmospherics(vec3 inPositionEye);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
+
+vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1)
+{
+ vec4 tcoord;
+
+ tcoord.x = dot(vpos, tp0);
+ tcoord.y = dot(vpos, tp1);
+ tcoord.z = tc.z;
+ tcoord.w = tc.w;
+
+ tcoord = mat * tcoord;
+
+ return tcoord;
+}
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ vec4 pos = modelview_matrix * vec4(position.xyz, 1.0);
+ vec3 norm = normalize(normal_matrix * normal);
+
+ calcAtmospherics(pos.xyz);
+
+ vec4 color = calcLighting(pos.xyz, norm, vec4(1.0));
+
+ vertex_color.rgb = color.rgb;
+
+ // Transform and pass tex coords
+ vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
+
+ vec4 t = vec4(texcoord1,0,1);
+
+ vary_texcoord0.zw = t.xy;
+ vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
+ vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 0d8dab0a41..8c8bd6d0d5 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file underWaterF.glsl
+ * @file class1\environment\underWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -47,7 +47,6 @@ uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
-uniform float waterFogDensity;
uniform float waterFogKS;
uniform vec2 screenRes;
@@ -56,41 +55,7 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
-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 vec4(1.0, 0.0, 1.0, 1.0);
- return color * D + kc * L;
- //depth /= 10.0;
- //return vec4(depth,depth,depth,0.0);
-}
+vec4 applyWaterFogView(vec3 pos, vec4 color);
void main()
{
@@ -108,5 +73,5 @@ void main()
vec4 fb = texture2D(screenTex, distort);
- frag_color = applyWaterFog(fb,view.xyz);
+ frag_color = applyWaterFogView(view.xyz, fb);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index 79bffab745..d370997123 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -32,7 +32,9 @@ out vec4 frag_color;
vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor);
-uniform sampler2D bumpMap;
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
uniform sampler2D screenTex;
uniform sampler2D refTex;
@@ -55,6 +57,13 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+
void main()
{
vec4 color;
@@ -65,9 +74,21 @@ void main()
vec3 viewVec = normalize(view.xyz);
//get wave 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;
+ 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(
@@ -136,6 +157,12 @@ void main()
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 4bdfce9260..df640cba05 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterFogF.glsl
+ * @file class1\environment\waterFogF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -25,7 +25,6 @@
-uniform vec4 lightnorm;
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
@@ -33,42 +32,48 @@ uniform float waterFogKS;
vec3 getPositionEye();
-vec4 applyWaterFog(vec4 color)
+vec4 applyWaterFogView(vec3 pos, vec4 color)
{
- //normalize view vector
- vec3 view = normalize(getPositionEye());
- float es = -(dot(view, waterPlane.xyz));
+ 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;
+
+ 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;
- //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(getPositionEye() - int_v);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
+ return color;
+}
- 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);
-
- color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
-
- return color;
+vec4 applyWaterFog(vec4 color)
+{
+ //normalize view vector
+ return applyWaterFogView(getPositionEye(), color);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index 352cea7aaa..cc41e3f740 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -1,5 +1,5 @@
/**
- * @file waterV.glsl
+ * @file class1\environment\waterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -31,8 +31,8 @@ ATTRIBUTE vec3 position;
void calcAtmospherics(vec3 inPositionEye);
-uniform vec2 d1;
-uniform vec2 d2;
+uniform vec2 waveDir1;
+uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
@@ -86,10 +86,10 @@ void main()
//pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
+ vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * 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;
+ littleWave.xy = (v.xy) * vec2(0.45, 0.9) + waveDir2 * time * 0.13;
+ littleWave.zw = (v.xy) * vec2(0.1, 0.2) + waveDir1 * time * 0.1;
view.w = bigWave.y;
refCoord.w = bigWave.x;
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
index a96d04cc39..f6b31a5956 100644
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
@@ -38,7 +38,9 @@ VARYING vec2 vary_texcoord0;
void main()
{
- vec4 color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
- color.a *= custom_alpha;
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+ color.rgb = pow(color.rgb, vec3(0.45));
+ color.rgb *= vertex_color.rgb;
+ color.a *= max(custom_alpha, vertex_color.a);
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index 5c088b3a3c..b5bbbb5c73 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
@@ -25,14 +25,14 @@
#extension GL_ARB_texture_rectangle : enable
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-/*[EXTRA_CODE_HERE]*/
-
uniform sampler2D glowMap;
uniform sampler2DRect screenMap;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index cad5b9ff04..0bb48061e0 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightAlphaMaskF.glsl
+ * @file class1\lighting\lightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -31,6 +31,9 @@ out vec4 frag_color;
uniform float minimum_alpha;
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
+uniform int no_atmo;
+
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
@@ -41,16 +44,19 @@ void default_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy);
- color *= vertex_color;
-
if (color.a < minimum_alpha)
{
discard;
}
+
+ color *= vertex_color;
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
+ color.rgb = atmosLighting(color.rgb);
+ color.rgb = scaleSoftClip(color.rgb);
+ }
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index 8918182853..b768d609f4 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightAlphaMaskNonIndexedF.glsl
+ * @file class1\lighting\lightAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index d6ebfcb825..9fd189358b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightF.glsl
+ * @file class1\lighting\lightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 5740987ab1..1855cfceeb 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -30,7 +30,10 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
-uniform float texture_gamma;
+uniform float texture_gamma; // either 1.0 or 2.2; see: "::TEXTURE_GAMMA"
+
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -50,9 +53,17 @@ void fullbright_lighting()
color.rgb *= vertex_color.rgb;
color.rgb = pow(color.rgb, vec3(texture_gamma));
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
+ color.rgb = fullbrightAtmosTransport(color.rgb);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
+
+ //*TODO: Are we missing an inverse pow() here?
+ // class1\lighting\lightFullbrightF.glsl has:
+ // color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index c8771a3f1e..5fcdf3107c 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightF.glsl
+ * @file class1\lighting\lightFullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -34,6 +34,9 @@ VARYING vec2 vary_texcoord0;
uniform float texture_gamma;
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
+uniform int no_atmo;
+
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -43,9 +46,12 @@ void fullbright_lighting()
color.rgb = pow(color.rgb, vec3(texture_gamma));
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
+ color.rgb = fullbrightAtmosTransport(color.rgb);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
index f72f20b03d..e8e71beb44 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightNonIndexedAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
index 2738ff8947..11a0919086 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightF.glsl
+ * @file class1\lighting\lightFullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index c8282e9a51..5e966293c6 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyF.glsl
+ * @file class1\lighting\lightFullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -35,20 +35,37 @@ VARYING vec3 vary_texcoord1;
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 fullbrightScaleSoftClip(vec3 light);
+// See:
+// class1\deferred\fullbrightShinyF.glsl
+// class1\lighting\lightFullbrightShinyF.glsl
void fullbright_shiny_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy);
color.rgb *= vertex_color.rgb;
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 0)
+ {
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
-
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ }
+/*
+ // NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
+ else
+ {
+ vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
+ }
+*/
color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
index e7dbd4bbd2..3118453342 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyF.glsl
+ * @file class1\lighting\lightFullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
index 5886fc65be..f78e5e0e8a 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyWaterF.glsl
+ * @file class1\lighting\lightFullbrightShinyWaterF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
index cddc7d8df8..90668bd2b6 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightShinyWaterF.glsl
+ * @file class1\lighting\lightFullbrightShinyWaterF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 6dd3bb937f..d04cd79f4b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index d3dacf9bc4..27880b720c 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterF.glsl
+ * @file class1\lighting\lightFullbrightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
index 63f92a8844..3b9c04b22b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+ * @file class1\lighting\lightFullbrightWaterNonIndexedAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
index 0e68091e7c..e9fd8ac820 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFullbrightWaterF.glsl
+ * @file class1\lighting\lightFullbrightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
index 85cddc647d..13a6dde4aa 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFuncSpecularV.glsl
+ * @file class1/lighting\lightFuncSpecularV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,14 +23,6 @@
* $/LicenseInfo$
*/
-
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
float calcDirectionalSpecular(vec3 view, vec3 n, vec3 l)
{
return pow(max(dot(reflect(view, n),l), 0.0),8.0);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
index a9288b3df6..45701002b8 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightFuncV.glsl
+ * @file class1\lighting\lightFuncV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,8 +32,7 @@ float calcDirectionalLight(vec3 n, vec3 l)
return a;
}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -54,6 +53,6 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
//angular attenuation
da *= calcDirectionalLight(n, lv);
- return da;
+ return da;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
index 0aca768021..f9c7ad2ab3 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightF.glsl
+ * @file class1\lighting\lightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
index 9208c148ef..f621a00785 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyF.glsl
+ * @file class1\lighting\lightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -45,7 +45,7 @@ void shiny_lighting()
color.rgb *= vertex_color.rgb;
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
color.rgb = atmosLighting(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
index 92628faa68..2b6f414005 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyF.glsl
+ * @file class1\lighting\lightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
index 61841674e2..0f3371eba9 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyWaterF.glsl
+ * @file class1\lighting\lightShinyWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
index 0b6e835fd0..c607fa64cb 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightShinyWaterF.glsl
+ * @file class1\lighting\lightShinyWaterNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
index 24bf9b3cee..06aed40e26 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightSpecularV.glsl
+ * @file class1\lighting\lightSpecularV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,10 +27,10 @@
// All lights, no specular highlights
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
- return sumLightsSpecular(pos, norm, color, specularColor, baseCol);
+ return sumLightsSpecular(pos, norm, color, specularColor);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
index 8045809b82..5e39d1629d 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightV.glsl
+ * @file class1\lighting\lightV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,11 +26,18 @@
// All lights, no specular highlights
+vec3 atmosAmbient();
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
+float getAmbientClamp();
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight);
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
{
- return sumLights(pos, norm, color, baseLight);
+ vec4 c = sumLights(pos, norm, color);
+
+#if !defined(AMBIENT_KILL)
+ c.rgb += atmosAmbient() * color.rgb * 0.5 * getAmbientClamp();
+#endif
+
+ return c;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index 3426fea52f..0916797259 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterAlphaMaskF.glsl
+ * @file class1\lighting\lightWaterAlphaMaskF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index d9faa9b314..f2a84f1d42 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterAlphaMaskNonIndexedF.glsl
+ * @file class1\lighting\lightWaterAlphaMaskNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
index 00609e93cd..57ed993a66 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterF.glsl
+ * @file class1\lighting\lightWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
index 13ecb7a636..af5da1411b 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
@@ -1,5 +1,5 @@
/**
- * @file lightWaterF.glsl
+ * @file class1\lighting\lightWaterNonIndexedF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
index 7059ff31ae..7c3697c333 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsSpecularV.glsl
+ * @file class1\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,7 +26,7 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
@@ -34,7 +34,7 @@ vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0,0,0, color.a);
@@ -45,8 +45,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
col.rgb = scaleDownLight(col.rgb);
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz, atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb * color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb * specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
index 41288c21c1..0c3ea4231e 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class1\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,22 +28,27 @@ uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
- vec4 col;
+ vec4 col = vec4(0);
col.a = color.a;
col.rgb = light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
col.rgb = scaleDownLight(col.rgb);
- col.rgb += atmosAmbient(baseLight.rgb);
+
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+#endif
+
+#if !defined(SUNLIGHT_KILL)
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-
+#endif
+
col.rgb = min(col.rgb*color.rgb, 1.0);
-
return col;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
index a54c0caf81..31a262f1db 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
@@ -1,5 +1,5 @@
/**
- * @file fullbrightF.glsl
+ * @file objects/fullbrightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
index 79b552ee1a..1e244d9dfd 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
@@ -35,6 +35,7 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
+VARYING vec4 vary_position;
void calcAtmospherics(vec3 inPositionEye);
@@ -46,6 +47,9 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+
+ mat4 mvp = modelview_matrix * projection_matrix;
+ vary_position = mvp * vec4(position, 1.0);
vec4 norm = vec4(position.xyz, 1.0);
norm.xyz += normal.xyz;
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 7f3f84398b..4bb588335a 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -52,7 +52,7 @@ float calcDirectionalLight(vec3 n, vec3 l)
}
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+float calcLocalLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -91,8 +91,7 @@ void main()
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-
+ col.rgb += light_diffuse[2].rgb*calcLocalLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcLocalLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
vertex_color = col*color;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
index 591d6fc5c9..727bae19c0 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
@@ -36,7 +36,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
@@ -59,7 +59,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
vertex_color = color;
gl_Position = projection_matrix*vec4(pos, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index fdb3453cc5..4ba8194d03 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
@@ -39,7 +39,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
@@ -61,5 +61,5 @@ void main()
calcAtmospherics(pos.xyz);
- vertex_color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.0));
+ vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
index 0be52a52af..22821a2f76 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
@@ -38,7 +38,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -52,7 +52,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0.));
+ vec4 col = calcLighting(pos.xyz, norm, color);
vertex_color = col;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
index cb80697d15..e605676819 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
@@ -37,7 +37,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -54,7 +54,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
index 1c6e53b187..df31b5a79f 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
@@ -35,7 +35,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
@@ -56,7 +56,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
vertex_color = color;
gl_Position = projection_matrix*vec4(pos, 1.0);
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
index d4dee78793..945f80f31e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
@@ -37,7 +37,7 @@ uniform vec4 color;
uniform vec4 object_plane_t;
uniform vec4 object_plane_s;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
VARYING vec4 vertex_color;
@@ -70,7 +70,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, color, vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, color);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 37a20383e2..9ef7704b70 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -1,4 +1,4 @@
-/**
+/**
* @file simpleV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
@@ -28,13 +28,16 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
+// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
+uniform int no_atmo;
+
ATTRIBUTE vec3 position;
void passTextureIndex();
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
@@ -46,19 +49,23 @@ void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+ passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
-
-
-
- vec3 norm = normalize(normal_matrix * normal);
- calcAtmospherics(pos.xyz);
+ // SL-9632 HUDs are affected by Atmosphere
+ if (no_atmo == 1)
+ {
+ vertex_color = diffuse_color;
+ }
+ else
+ {
+ vec4 pos = (modelview_matrix * vert);
+ vec3 norm = normalize(normal_matrix * normal);
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vertex_color = color;
+ calcAtmospherics(pos.xyz);
-
+ vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
+ }
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
index fa01a27ec0..0227e6e3b8 100644
--- a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
@@ -31,8 +31,9 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
void calcAtmospherics(vec3 inPositionEye);
VARYING vec4 vertex_color;
@@ -53,8 +54,6 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
+ vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
vertex_color = color;
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index aacc503e13..4e0618e276 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsF.glsl
+ * @file class1\windlight\atmosphericsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,11 +23,26 @@
* $/LicenseInfo$
*/
+vec3 atmosFragAmbient(vec3 light, vec3 sunlit)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+
+vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit)
+{
+ return light * sunlit;
+}
vec3 atmosLighting(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
new file mode 100644
index 0000000000..ea2690ba09
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -0,0 +1,134 @@
+/**
+ * @file class1\windlight\atmosphericsFuncs.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+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;
+
+float getAmbientClamp() { return 1.0f; }
+
+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);
+
+ // brightness of surface both sunlight and ambient
+ sunlit = sunlight.rgb * 0.5;
+ amblit = tmpAmbient.rgb * .25;
+ additive *= vec3(1.0 - combined_haze);
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
new file mode 100644
index 0000000000..206a51db27
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class1\windlight\atmosphericsHelpersF.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 vec4 sunlight_color;
+uniform vec4 light_ambient;
+uniform int no_atmo;
+
+vec3 atmosAmbient()
+{
+ if (no_atmo == 1) return vec3(0.16);
+ return light_ambient.rgb;
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return sunlight_color.rgb * lightIntensity;
+}
+
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return sunlight_color.rgb;
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 6ff860362c..c266f9732f 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsHelpersV.glsl
+ * @file class1\windlight\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,33 +23,35 @@
* $/LicenseInfo$
*/
-uniform vec4 sunlight_color_copy;
+uniform vec4 sunlight_color;
uniform vec4 light_ambient;
+uniform int no_atmo;
-vec3 atmosAmbient(vec3 light)
+vec3 atmosAmbient()
{
- return light + light_ambient.rgb;
+ if (no_atmo == 1) return vec3(0.66);
+ return light_ambient.rgb;
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
- return sunlight_color_copy.rgb * lightIntensity;
+ return sunlight_color.rgb * lightIntensity;
}
vec3 atmosGetDiffuseSunlightColor()
{
- return sunlight_color_copy.rgb;
+ return sunlight_color.rgb;
}
vec3 scaleDownLight(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
vec3 scaleUpLight(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
index 76d7d5059d..20457ad125 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsV.glsl
+ * @file class1\windlight\atmosphericsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -29,7 +29,7 @@ void setPositionEye(vec3 v);
void calcAtmospherics(vec3 inPositionEye)
{
- /* stub function for fallback compatibility on class1 hardware */
- setPositionEye(inPositionEye);
+ /* stub function for fallback compatibility on class1 hardware */
+ setPositionEye(inPositionEye);
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 8bdae328bd..3b4d358cfa 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -1,30 +1,37 @@
-/**
- * @file atmosphericVarsF.glsl
+/**
+ * @file class1\windlight\atmosphericVarsF.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 getPositionEye()
-{
- return vec3(0,0,0);
-}
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
+
+vec3 getAmblitColor() { return vec3(0, 0, 0); }
+
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
+
+vec3 getAtmosAttenuation() { return vec3(vary_AtmosAttenuation); }
+
+vec3 getSunlitColor() { return vec3(0, 0, 0); }
+
+vec3 getPositionEye() { return vec3(0, 0, 0); }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 8ec9ae617c..1fea2c3628 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -1,36 +1,56 @@
-/**
- * @file atmosphericVarsV.glsl
+/**
+ * @file class1\windlight\atmosphericVarsV.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$
*/
-
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
-vec3 getPositionEye()
+vec3 additive_color;
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
+vec3 position_eye;
+
+vec3 getSunlitColor() { return sunlit_color; }
+void setSunlitColor(vec3 v) { sunlit_color = v; }
+
+vec3 getAdditiveColor() { return additive_color; }
+void setAdditiveColor(vec3 v)
{
- return vec3(0,0,0);
+ additive_color = v;
+ vary_AdditiveColor = v;
}
-void setPositionEye(vec3 v)
+vec3 getAmblitColor() { return amblit_color; }
+void setAmblitColor(vec3 v) { amblit_color = v; }
+
+vec3 getAtmosAttenuation() { return atmos_attenuation; }
+void setAtmosAttenuation(vec3 v)
{
-
+ atmos_attenuation = v;
+ vary_AtmosAttenuation = v;
}
+
+vec3 getPositionEye() { return position_eye; }
+void setPositionEye(vec3 v) { position_eye = v; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index 636d4af006..f83434b7ec 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
@@ -1,33 +1,38 @@
-/**
- * @file atmosphericVarsWaterF.glsl
+/**
+ * @file class1\windlight\atmosphericVarsWaterF.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$
*/
-
VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
+
+vec3 getSunlitColor() { return vec3(0, 0, 0); }
+
+vec3 getAmblitColor() { return vec3(0, 0, 0); }
+
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
+vec3 getAtmosAttenuation() { return vary_AtmosAttenuation; }
+vec3 getPositionEye() { return vary_PositionEye; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index 8afcc20f6d..65d1176777 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
@@ -1,37 +1,51 @@
-/**
- * @file atmosphericVarsWaterV.glsl
+/**
+ * @file class1\windlight\atmosphericVarsWaterV.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$
*/
-
-
+
VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
+
+vec3 getSunlitColor() { return sunlit_color; }
+void setSunlitColor(vec3 v) { sunlit_color = v; }
+
+vec3 getAmblitColor() { return amblit_color; }
+void setAmblitColor(vec3 v) { amblit_color = v; }
-void setPositionEye(vec3 v)
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
+void setAdditiveColor(vec3 v) { vary_AdditiveColor = v; }
+
+vec3 getAtmosAttenuation() { return atmos_attenuation; }
+void setAtmosAttenuation(vec3 v)
{
- vary_PositionEye = v;
+ atmos_attenuation = v;
+ vary_AtmosAttenuation = v;
}
+
+vec3 getPositionEye() { return vary_PositionEye; }
+void setPositionEye(vec3 v) { vary_PositionEye = v; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
new file mode 100644
index 0000000000..82fad4db5a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
@@ -0,0 +1,127 @@
+/**
+ * @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
new file mode 100644
index 0000000000..09b6004481
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
@@ -0,0 +1,61 @@
+/**
+ * @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/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
index 62f4e51449..fc51e81177 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
@@ -1,5 +1,5 @@
/**
- * @file gammaF.glsl
+ * @file class1\windlight\gammaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,17 +23,30 @@
* $/LicenseInfo$
*/
+uniform int no_atmo;
-
-uniform vec4 gamma;
+vec3 scaleSoftClipFrag(vec3 light)
+{
+ // For compatibility with lower cards. Do nothing.
+ return light;
+}
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- // For compatibility with lower cards. Do nothing.
+vec3 scaleSoftClip(vec3 light)
+{
+ // For compatibility with lower cards. Do nothing
+ return light;
+}
+
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ // For compatibility with lower cards. Do nothing
return light;
}
-vec3 fullbrightScaleSoftClip(vec3 light) {
- return scaleSoftClip(light);
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ // For compatibility with lower cards. Do nothing
+ return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
new file mode 100644
index 0000000000..2425a2ad04
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -0,0 +1,66 @@
+/**
+ * @file class1\wl\moonF.glsl
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2005, 2020 Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#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 vec4 color;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform vec3 moon_dir;
+uniform float moon_brightness;
+uniform sampler2D diffuseMap;
+
+VARYING vec2 vary_texcoord0;
+
+vec3 scaleSoftClip(vec3 light);
+
+void main()
+{
+ // Restore Pre-EEP alpha fade moon near horizon
+ float fade = 1.0;
+ if( moon_dir.z > 0 )
+ fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
+
+ vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+// c.rgb = pow(c.rgb, vec3(0.7f)); // can't use "srgb_to_linear(color.rgb)" as that is a deferred only function
+ c.rgb *= moonlight_color.rgb;
+ c.rgb *= moon_brightness;
+
+ c.rgb *= fade;
+ c.a *= fade;
+
+ c.rgb = scaleSoftClip(c.rgb);
+
+ frag_color = vec4(c.rgb, c.a);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
new file mode 100644
index 0000000000..2fceb5f743
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
@@ -0,0 +1,44 @@
+/**
+ * @file class1\wl\moonV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 2020 Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz, 1.0);
+ vec4 pos = (modelview_matrix * vert);
+
+ gl_Position = modelview_projection_matrix*vert;
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
new file mode 100644
index 0000000000..5a41dc644a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @file class1\wl\sunDiscF.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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+vec3 fullbrightAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+uniform sampler2D diffuseMap;
+uniform sampler2D altDiffuseMap;
+uniform float blend_factor; // interp factor between sun A/B
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void main()
+{
+ vec4 sunA = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 sunB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 c = mix(sunA, sunB, blend_factor);
+
+// SL-9806 stars poke through
+// c.a *= sun_fade;
+
+ c.rgb = fullbrightAtmosTransport(c.rgb);
+ c.rgb = fullbrightScaleSoftClip(c.rgb);
+ frag_color = c;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
new file mode 100644
index 0000000000..6c0e795f6b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class1\wl\sunDiscV.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_matrix;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 vary_texcoord0;
+VARYING float sun_fade;
+
+void calcAtmospherics(vec3 eye_pos);
+
+void main()
+{
+ //transform vertex
+ vec3 offset = vec3(0, 0, 50);
+ vec4 vert = vec4(position.xyz - offset, 1.0);
+ vec4 pos = modelview_projection_matrix*vert;
+
+ sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
+ gl_Position = pos;
+
+ calcAtmospherics(pos.xyz);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
index 7c95ecdb14..a937d9fa99 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
@@ -1,5 +1,5 @@
/**
- * @file transportF.glsl
+ * @file class1/windlight/transportF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,25 +22,35 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+uniform int no_atmo;
-vec3 atmosTransport(vec3 light)
+vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
{
- /* stub function for fallback compatibility on class1 hardware */
+ /* stub function for fallback compatibility on class1 hardware */
return light;
}
-vec3 fullbrightAtmosTransport(vec3 light)
+vec3 atmosTransport(vec3 light)
{
/* stub function for fallback compatibility on class1 hardware */
- return light;
+ return light;
+}
+
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
+vec3 fullbrightAtmosTransport(vec3 light)
+{
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
+}
vec3 fullbrightShinyAtmosTransport(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ /* stub function for fallback compatibility on class1 hardware */
+ return light;
}
-
diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
index 5af9f5c902..563c5f562b 100644
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
@@ -37,7 +37,7 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol);
+vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
void calcAtmospherics(vec3 inPositionEye);
void main()
@@ -53,7 +53,7 @@ void main()
// vec4 specular = specularColor;
vec4 specular = vec4(1.0);
- vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular, vec4(0.0));
+ vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular);
vertex_color = color;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
new file mode 100644
index 0000000000..67b98e0fb1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
@@ -0,0 +1,32 @@
+/**
+ * @file class2/deferred/indirect.glsl
+ *
+ * $LicenseInfo:firstyear=2018&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$
+ */
+
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
+
+vec3 getIndirect(vec3 ambient, vec3 norm, vec4 pos, vec2 pos_screen)
+{
+ return ambient * calcAmbientOcclusion(pos, norm, pos_screen);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index b9bb522842..1b7a1cc6ec 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -71,294 +71,229 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 srgb_to_linear(vec3 cs);
+vec3 getNorm(vec2 pos_screen);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- 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);
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ 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));
-
- float edge = 0.25*det;
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
+ 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);
- ret = correctWithGamma(ret);
-
- 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;
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ 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;
}
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
-
- 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 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
+ 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);
+
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)
- {
- discard;
- }
-
- float shadow = 1.0;
-
- if (proj_shadow_idx >= 0)
- {
- vec4 shd = texture2DRect(lightMap, frag.xy);
- float sh[2];
- sh[0] = shd.b;
- sh[1] = shd.a;
- shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
-
- norm = decode_normal(norm.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+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;
- 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 = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
-
- vec3 dlit = vec3(0, 0, 0);
-
- 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)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
-
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
-
- 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)*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)
- {
- 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));
-
- 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 (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)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
+
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
+ 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);
+
+ if (dist >= size)
+ {
+ discard;
+ }
+ dist /= size;
+
+ float shadow = 1.0;
+
+ if (proj_shadow_idx >= 0)
+ {
+ vec4 shd = texture2DRect(lightMap, frag.xy);
+ 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+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;
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
+
+ lv = proj_origin-pos.xyz;
+ lv = normalize(lv);
+ float da = dot(norm, lv);
+
+ vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
+ 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)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
+
+ 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;
+
+ // unshadowed for consistency between forward and deferred?
+ amb_da += (da*0.5+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);
+
+ // use unshadowed for consistency between forward and deferred?
+ 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)
+ {
+ 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));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
+ }
+ }
+
+ 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)
+ {
+ 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;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, 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));
-
- frag_color.rgb = col;
- frag_color.a = 0.0;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
+ }
+ }
+ }
+#endif
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
+ //output linear
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
new file mode 100644
index 0000000000..6841a8194f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -0,0 +1,199 @@
+/**
+ * @file class2/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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+// SKY ////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+// Inputs
+uniform vec3 camPosLocal;
+
+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 sun_moon_glow_factor;
+
+uniform vec4 cloud_color;
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+VARYING vec3 pos;
+
+/////////////////////////////////////////////////////////////////////////
+// The fragment shader for the sky
+/////////////////////////////////////////////////////////////////////////
+
+uniform sampler2D rainbow_map;
+uniform sampler2D halo_map;
+
+uniform float moisture_level;
+uniform float droplet_radius;
+uniform float ice_level;
+
+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)
+{
+ d = clamp(d, 0.1, 1.0);
+ float v = sqrt(clamp(1 - (d * d), 0, 1));
+ return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+}
+
+/// Soft clips the light with a gamma correction
+vec3 scaleSoftClip(vec3 light);
+
+void main()
+{
+ // World / view / projection
+ // Get relative position (offset why?)
+ vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ // Adj position vector to clamp altitude
+ if (rel_pos.y > 0.)
+ {
+ rel_pos *= (max_y / rel_pos.y);
+ }
+ if (rel_pos.y < 0.)
+ {
+ rel_pos *= (-32000. / rel_pos.y);
+ }
+
+ // Normalized
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
+
+ // Initialize temp variables
+ 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);
+
+ // 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;
+
+ // 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);
+ sunlight *= exp(-light_atten * off_axis);
+
+ // Distance
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist);
+
+ // Compute haze glow
+ float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
+ 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"
+ // For sun, add to glow. For moon, remove glow entirely. SL-13768
+ 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)
+ + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
+
+ // Final atmosphere additive
+ color *= (1. - combined_haze);
+
+ // 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;
+
+ // 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)
+ + haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
+
+ // Attenuate cloud color by atmosphere
+ combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
+
+ // At horizon, blend high altitude sky color towards the darker color below the clouds
+ color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
+
+ float optic_d = dot(rel_pos_norm, lightnorm.xyz);
+ vec3 halo_22 = halo22(optic_d);
+ color.rgb += rainbow(optic_d);
+ color.rgb += halo_22;
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ // 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
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
new file mode 100644
index 0000000000..bcf775577a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file WLSkyV.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;
+
+// SKY ////////////////////////////////////////////////////////////////////////
+// The vertex shader for creating the atmospheric sky
+///////////////////////////////////////////////////////////////////////////////
+
+VARYING vec3 pos;
+
+void main()
+{
+
+ // World / view / projection
+ pos = position.xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index f7832521fa..7700d16007 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -1,29 +1,30 @@
-/**
- * @file softenLightF.glsl
+/**
+ * @file class2/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]*/
@@ -38,457 +39,120 @@ uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
uniform float blur_size;
uniform float blur_fidelity;
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-uniform vec4 gamma;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-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 global_gamma;
-uniform float scene_light_strength;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
-uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
VARYING vec2 vary_fragcoord;
-vec3 vary_PositionEye;
-
-vec3 vary_SunlitColor;
-vec3 vary_AmblitColor;
-vec3 vary_AdditiveColor;
-vec3 vary_AtmosAttenuation;
-
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-}
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
+float getAmbientClamp();
+vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFrag(vec3 l);
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
+vec3 fullbrightScaleSoftClip(vec3 light);
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
-}
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition_d(vec2 pos_screen, float depth)
-{
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- return getPosition_d(pos_screen, depth);
-}
-
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-vec3 getSunlitColor()
-{
- return vary_SunlitColor;
-}
-vec3 getAmblitColor()
-{
- return vary_AmblitColor;
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- vary_SunlitColor = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- vary_AmblitColor = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- vary_AtmosAttenuation = v;
-}
-
-void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * 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);
- */
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- /*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
- setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
- setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
-
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-}
+void main()
+{
+ 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);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ float light_gamma = 1.0 / 1.3;
+ da = pow(da, light_gamma);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc);
+ diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025
+ vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
+
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
+
+ vec3 color = vec3(0);
+ float bloom = 0.0;
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
+
+ color.rgb = amblit;
+
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
+ color.rgb *= ambient;
+
+ vec3 sun_contrib = min(da, scol) * sunlit;
+ color.rgb += sun_contrib;
+ color.rgb *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ float sa = dot(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;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+ color.rgb += spec_contrib;
+ }
+
+ color.rgb = mix(color.rgb, diffuse.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.rgb, reflected_color, envIntensity);
+ }
+
+ if (norm.w < 0.5)
+ {
+ color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
+ color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
+ }
#ifdef WATER_FOG
-uniform vec4 waterPlane;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-
-vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
-{
- //normalize view vector
- vec3 view = normalize(pos);
- 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;
-
- 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 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ bloom = fogged.a;
#endif
-vec3 atmosLighting(vec3 light)
-{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
-}
-
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
- return light;
-}
-
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
-}
-
-
-
-vec3 atmosGetDiffuseSunlightColor()
-{
- return getSunlitColor();
-}
-
-vec3 scaleDownLight(vec3 light)
-{
- return (light / scene_light_strength );
-}
-
-vec3 scaleUpLight(vec3 light)
-{
- return (light * scene_light_strength);
-}
-
-vec3 atmosAmbient(vec3 light)
-{
- return getAmblitColor() + light / 2.0;
-}
-
-vec3 atmosAffectDirectionalLight(float lightIntensity)
-{
- return getSunlitColor() * lightIntensity;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
-
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- //soft clip effect:
- return light;
-}
-
-void main()
-{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPosition_d(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = decode_normal(norm.xy); // unpack norm
-
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
- float light_gamma = 1.0/1.3;
- da = pow(da, light_gamma);
-
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
-
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb);
-
- vec3 col;
- float bloom = 0.0;
- {
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
- scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
-
- float scol = max(scol_ambocc.r, diffuse.a);
-
-
-
- float ambocc = scol_ambocc.g;
-
- calcAtmospherics(pos.xyz, ambocc);
-
- col = atmosAmbient(vec3(0));
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb *= ambient;
-
- col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
-
- col *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- // the old infinite-sky shiny reflection
- //
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(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;
- col += spec_contrib;
- }
-
-
- col = mix(col, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 refcol = textureCube(environmentMap, env_vec).rgb;
-
- col = mix(col.rgb, refcol,
- envIntensity);
-
- }
-
- if (norm.w < 0.5)
- {
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- }
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
-
- col = srgb_to_linear(col);
-
- //col = vec3(1,0,1);
- //col.g = envIntensity;
- }
-
- frag_color.rgb = col;
- frag_color.a = bloom;
+ // convert to linear as fullscreen lights need to sum in linear colorspace
+ // and will be gamma (re)corrected downstream...
+ frag_color.rgb = srgb_to_linear(color.rgb);
+ frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
index c840d72784..bd11aa3f05 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
@@ -31,12 +31,19 @@ uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
+// forwards
+void setAtmosAttenuation(vec3 c);
+void setAdditiveColor(vec3 c);
+
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
gl_Position = pos;
-
-
+
+ // appease OSX GLSL compiler/linker by touching all the varyings we said we would
+ setAtmosAttenuation(vec3(1));
+ setAdditiveColor(vec3(0));
+
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 81af1fdc8a..774f537821 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -71,70 +71,14 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lte.r ? low_range.r : high_range.r;
- result.g = lte.g ? low_range.g : high_range.g;
- result.b = lte.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lte);
-#endif
-
-}
-
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
- bvec3 lt = lessThan(cl,vec3(0.0031308));
-
-#ifdef OLD_SELECT
- vec3 result;
- result.r = lt.r ? low_range.r : high_range.r;
- result.g = lt.g ? low_range.g : high_range.g;
- result.b = lt.b ? low_range.b : high_range.b;
- return result;
-#else
- return mix(high_range, low_range, lt);
-#endif
-
-}
-
-vec4 correctWithGamma(vec4 col)
-{
- return vec4(srgb_to_linear(col.rgb), col.a);
-}
+vec3 getNorm(vec2 pos_screen);
+vec3 srgb_to_linear(vec3 c);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
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);
@@ -153,7 +97,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -171,7 +115,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -182,22 +126,15 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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 getPosition(vec2 pos_screen);
void main()
{
+ vec3 col = vec3(0,0,0);
+
+#if defined(LOCAL_LIGHT_KILL)
+ discard;
+#else
vec4 frag = vary_fragcoord;
frag.xyz /= frag.w;
frag.xyz = frag.xyz*0.5+0.5;
@@ -206,26 +143,26 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
float dist = length(lv);
+
+ if (dist >= size)
+ {
+ discard;
+ }
dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
vec4 shd = texture2DRect(lightMap, frag.xy);
- float sh[2];
- sh[0] = shd.b;
- sh[1] = shd.a;
- shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
+ 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 = decode_normal(norm.xy);
+ norm = getNorm(frag.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -252,12 +189,8 @@ void main()
lv = normalize(lv);
float da = dot(norm, lv);
- vec3 col = vec3(0,0,0);
-
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
vec4 spec = texture2DRect(specularRect, frag.xy);
-
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
@@ -280,23 +213,21 @@ void main()
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;
+
+ amb_da += (da*0.5+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)*proj_ambiance;
-
+ 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;
- }
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ }
if (spec.a > 0.0)
{
@@ -317,14 +248,11 @@ void main()
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;
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
}
}
-
-
-
-
if (envIntensity > 0.0)
{
@@ -354,10 +282,12 @@ void main()
}
}
}
+#endif
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
+ //output linear colors as gamma correction happens down stream
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 265da8df99..8abdeae5ae 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -35,228 +35,26 @@ out vec4 frag_color;
//class 2, shadows, no SSAO
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-
-
// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
-
-uniform vec2 shadow_res;
uniform float shadow_bias;
-uniform float shadow_offset;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPosition(vec2 pos_screen);
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
-
- return shadow*0.2;
-}
-
-float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += spot_shadow_bias*scl;
- stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- vec2 off = 1.0/proj_shadow_res;
- off.y *= 1.5;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
-
- return shadow*0.2;
-}
+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;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy); // unpack norm
-
- /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
- {
- frag_color = vec4(0.0); // doesn't matter
- return;
- }*/
-
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
-
- vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- if (dp_directional_light == 0.0)
- {
- // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
- shadow = 0.0;
- }
- else
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
- weight += w;
- }
-
-
- shadow /= weight;
-
- // take the most-shadowed value out of these two:
- // * the blurred sun shadow in the light (shadow) map
- // * an unblurred dot product between the sun and this norm
- // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
- shadow = min(shadow, dp_directional_light);
-
- //lpos.xy /= lpos.w*32.0;
- //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
- //{
- // shadow = 0.0;
- //}
-
- }
- }
- else
- {
- // more distant than the shadow map covers
- shadow = 1.0;
- }
-
- frag_color[0] = shadow;
- frag_color[1] = 1.0;
-
- spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
-
- //spotlight shadow 1
- vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
-
- //spotlight shadow 2
- lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
-
- //frag_color.rgb = pos.xyz;
- //frag_color.b = shadow;
+ 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/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 5c6fe30daa..64d99bae2c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -1,5 +1,5 @@
/**
- * @file sunLightSSAOF.glsl
+ * @file class2/deferred/sunLightSSAOF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -34,290 +34,24 @@ out vec4 frag_color;
//class 2 -- shadows and SSAO
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DShadow shadowMap0;
-uniform sampler2DShadow shadowMap1;
-uniform sampler2DShadow shadowMap2;
-uniform sampler2DShadow shadowMap3;
-uniform sampler2DShadow shadowMap4;
-uniform sampler2DShadow shadowMap5;
-uniform sampler2D noiseMap;
-
-
// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
VARYING vec2 vary_fragcoord;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-uniform vec2 proj_shadow_res;
-uniform vec3 sun_dir;
-
-uniform vec2 shadow_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-vec2 encode_normal(vec3 n)
-{
- float f = sqrt(8 * n.z + 8);
- return n.xy / f + 0.5;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- 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;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).r;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- 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;
-}
-
-vec2 getKern(int i)
-{
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- return kern[i];
-}
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- float ret = 1.0;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- float points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- float funky_val = (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) ? 1.0 : 0.0;
- angle_hidden = angle_hidden + funky_val * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- float diffz_val = (diff.z > -1.0) ? 1.0 : 0.0;
- points = points + diffz_val;
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/points, 1.0);
-
- float points_val = (points > 0.0) ? 1.0 : 0.0;
- ret = (1.0 - (points_val * angle_hidden));
-
- ret = max(ret, 0.0);
- return min(ret, 1.0);
-}
-
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
- float cs = shadow2D(shadowMap, stc.xyz).x;
-
- float shadow = cs;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
-
- return shadow*0.2;
-}
-
-float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
-{
- stc.xyz /= stc.w;
- stc.z += spot_shadow_bias*scl;
- stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
-
- float cs = shadow2D(shadowMap, stc.xyz).x;
- float shadow = cs;
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
- vec2 off = 1.0/proj_shadow_res;
- off.y *= 1.5;
-
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
-
- return shadow*0.2;
-}
+float sampleDirectionalShadow(vec3 shadow_pos, vec3 norm, vec2 pos_screen);
+float sampleSpotShadow(vec3 shadow_pos, vec3 norm, int index, vec2 pos_screen);
+float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
void main()
{
- vec2 pos_screen = vary_fragcoord.xy;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = decode_normal(norm.xy); // unpack norm
-
- /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
- {
- frag_color = vec4(0.0); // doesn't matter
- return;
- }*/
-
- float shadow = 0.0;
- float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz;
- vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
-
- vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
-
- if (spos.z > -shadow_clip.w)
- {
- if (dp_directional_light == 0.0)
- {
- // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
- shadow = 0.0;
- }
- else
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
- weight += w;
- }
-
-
- shadow /= weight;
-
- // take the most-shadowed value out of these two:
- // * the blurred sun shadow in the light (shadow) map
- // * an unblurred dot product between the sun and this norm
- // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
- shadow = min(shadow, dp_directional_light);
-
- //lpos.xy /= lpos.w*32.0;
- //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
- //{
- // shadow = 0.0;
- //}
-
- }
- }
- else
- {
- // more distant than the shadow map covers
- shadow = 1.0;
- }
-
- frag_color[0] = shadow;
- frag_color[1] = calcAmbientOcclusion(pos, norm);
-
- spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
-
- //spotlight shadow 1
- vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
-
- //spotlight shadow 2
- lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec4 pos = getPosition(pos_screen);
+ vec3 norm = getNorm(pos_screen);
- //frag_color.rgb = pos.xyz;
- //frag_color.b = shadow;
+ frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ frag_color.g = 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/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
index 3acf9fe883..89d9d1bde3 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class2\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,16 +28,16 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -53,8 +53,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz, atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb*color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index c9987ef3b9..30ca88afd2 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class2\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,9 +24,8 @@
*/
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
@@ -35,24 +34,27 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
-
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
-
+ col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb = scaleDownLight(col.rgb);
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+i#endif
+
// Add windlight lights
- col.rgb += atmosAmbient(baseLight.rgb);
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-
+
+#if !defined(SUNLIGHT_KILL)
col.rgb = min(col.rgb*color.rgb, 1.0);
-
+#endif
+
return col;
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index fea3cbf69b..ee9c990b12 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsF.glsl
+ * @file class2\wl\atmosphericsF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,23 +22,25 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
vec3 getAdditiveColor();
vec3 getAtmosAttenuation();
+vec3 scaleSoftClipFrag(vec3 light);
-uniform sampler2D cloudMap;
-uniform vec4 cloud_pos_density1;
+uniform int no_atmo;
-vec3 atmosLighting(vec3 light)
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
{
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor();
- return (2.0 * light);
+ 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/class2/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
new file mode 100644
index 0000000000..5788871744
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file class2\wl\atmosphericsHelpersV.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$
+ */
+
+// Output variables
+
+uniform float scene_light_strength;
+uniform int no_atmo;
+
+vec3 atmosFragAmbient(vec3 light, vec3 amblit)
+{
+ if (no_atmo == 1) return light;
+ return amblit + light / 2.0;
+}
+
+vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit)
+{
+ return sunlit * lightIntensity;
+}
+
+vec3 scaleDownLightFrag(vec3 light)
+{
+ return (light / scene_light_strength );
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
index 62a034ce05..9c42b84eca 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsHelpersV.glsl
+ * @file class2\wl\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -33,29 +33,31 @@ vec3 getAtmosAttenuation();
vec3 getPositionEye();
uniform float scene_light_strength;
+uniform int no_atmo;
-vec3 atmosAmbient(vec3 light)
+vec3 atmosAmbient()
{
- return getAmblitColor() + light / 2.0;
+ if (no_atmo == 1) return vec3(0.16);
+ return getAmblitColor();
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
- return getSunlitColor() * lightIntensity;
+ return getSunlitColor() * lightIntensity;
}
vec3 atmosGetDiffuseSunlightColor()
{
- return getSunlitColor();
+ return getSunlitColor();
}
vec3 scaleDownLight(vec3 light)
{
- return (light / scene_light_strength );
+ return (light / scene_light_strength );
}
vec3 scaleUpLight(vec3 light)
{
- return (light * scene_light_strength);
+ return (light * scene_light_strength);
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index d174805cc0..4c418e414f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericsV.glsl
+ * @file class2\wl\atmosphericsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,10 +22,14 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
// VARYING param funcs
+
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
+
void setSunlitColor(vec3 v);
void setAmblitColor(vec3 v);
void setAdditiveColor(vec3 v);
@@ -34,124 +38,19 @@ void setPositionEye(vec3 v);
vec3 getAdditiveColor();
-//VARYING vec4 vary_CloudUVs;
-//VARYING float vary_CloudDensity;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-//uniform vec4 camPosWorld;
-
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-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;
+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);
-
- //(TERRAIN) limit altitude
- if (P.y > max_y) P *= (max_y / P.y);
- if (P.y < -max_y) P *= (-max_y / P.y);
-
- vec3 tmpLightnorm = lightnorm.xyz;
-
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- vec4 temp1 = vec4(0);
- vec3 temp2 = vec3(0);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
- //I had thought blue_density and haze_density should have equal weighting,
- //but attenuation due to haze_density tends to seem too strong
-
- temp1 = blue_density + vec4(haze_density);
- blue_weight = blue_density / temp1;
- haze_weight = vec4(haze_density) / temp1;
-
- //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
- temp2.y = max(0.0, tmpLightnorm.y);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // main atmospheric scattering line integral
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z * distance_multiplier);
-
- //final atmosphere attenuation factor
- setAtmosAttenuation(temp1.rgb);
- //vary_AtmosAttenuation = distance_multiplier / 10000.;
- //vary_AtmosAttenuation = density_multiplier * 100.;
- //vary_AtmosAttenuation = vec4(Plen / 100000., 0., 0., 1.);
-
- //compute haze glow
- //(can use temp2.x as temp because we haven't used it yet)
- temp2.x = dot(Pn, tmpLightnorm.xyz);
- temp2.x = 1. - temp2.x;
- //temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .03); //was glow.y
- //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- //higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- //glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- //add "minimum anti-solar illumination"
- temp2.x += .25;
-
-
- //increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
-
- //haze color
- setAdditiveColor(
- vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
- + tmpAmbient)));
-
- //brightness of surface both sunlight and ambient
- setSunlitColor(vec3(sunlight * .5));
- setAmblitColor(vec3(tmpAmbient * .25));
- setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
-
- // vary_SunlitColor = vec3(0);
- // vary_AmblitColor = vec3(0);
- // vary_AdditiveColor = vec4(Pn, 1.0);
-
- /*
- const float cloudShadowScale = 100.;
- // Get cloud uvs for shadowing
- vec3 cloudPos = inPositionEye + camPosWorld - cloudShadowScale / 2.;
- vary_CloudUVs.xy = cloudPos.xz / cloudShadowScale;
-
- // We can take uv1 and multiply it by (TerrainSpan / CloudSpan)
-// cloudUVs *= (((worldMaxZ - worldMinZ) * 20) /40000.);
- vary_CloudUVs *= (10000./40000.);
-
- // Offset by sun vector * (CloudAltitude / CloudSpan)
- vary_CloudUVs.x += tmpLightnorm.x / tmpLightnorm.y * (3000./40000.);
- vary_CloudUVs.y += tmpLightnorm.z / tmpLightnorm.y * (3000./40000.);
- */
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+ vec3 tmpsunlit = vec3(1);
+ vec3 tmpamblit = vec3(1);
+ vec3 tmpaddlit = vec3(1);
+ vec3 tmpattenlit = vec3(1);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ calcAtmosphericVars(inPositionEye, light_dir, 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, false);
+ setSunlitColor(tmpsunlit);
+ setAmblitColor(tmpamblit);
+ setAdditiveColor(tmpaddlit);
+ setAtmosAttenuation(tmpattenlit);
}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
index 765b0927c3..07733bda18 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVars.glsl
+ * @file class2\wl\atmosphericVarsF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,7 +24,6 @@
*/
-VARYING vec3 vary_SunlitColor;
VARYING vec3 vary_AdditiveColor;
VARYING vec3 vary_AtmosAttenuation;
@@ -32,14 +31,17 @@ vec3 getSunlitColor()
{
return vec3(0,0,0);
}
+
vec3 getAmblitColor()
{
return vec3(0,0,0);
}
+
vec3 getAdditiveColor()
{
return vary_AdditiveColor;
}
+
vec3 getAtmosAttenuation()
{
return vec3(vary_AtmosAttenuation);
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
index 99dbee15ee..31109aed31 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVars.glsl
+ * @file class2\wl\atmosphericVars.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
index 163ef26444..22e16b7e0f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterF.glsl
+ * @file class2\wl\atmosphericVarsWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
index 553f6752e6..0f2a3ee527 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
@@ -1,5 +1,5 @@
/**
- * @file atmosphericVarsWaterV.glsl
+ * @file class2\wl\atmosphericVarsWaterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 96c70651b1..fa928d993e 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsF.glsl
+ * @file class2\wl\cloudsF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,7 +22,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
+/*[EXTRA_CODE_HERE]*/
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -36,69 +38,94 @@ out vec4 frag_color;
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;
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 gamma;
+uniform float cloud_scale;
+uniform float cloud_variance;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
+VARYING float altitude_blend_factor;
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
+vec3 scaleSoftClip(vec3 light);
- return 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;
+ // Set variables
+ vec2 uv1 = vary_texcoord0.xy;
+ vec2 uv2 = vary_texcoord1.xy;
+
+ vec4 cloudColorSun = vary_CloudColorSun;
+ vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ float cloudDensity = vary_CloudDensity;
+ vec2 uv3 = vary_texcoord2.xy;
+ vec2 uv4 = vary_texcoord3.xy;
+
+ if (cloud_scale < 0.001)
+ {
+ discard;
+ }
+
+ 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);
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
- vec2 uv3 = vary_texcoord2.xy;
- vec2 uv4 = vary_texcoord3.xy;
+ cloudDensity *= 1.0 - (density_variance * density_variance);
- // Offset texture coords
- uv1 += cloud_pos_density1.xy; //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
+ // 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.);
- // Compute alpha1, the main cloud opacity
- float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, 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;
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
+ alpha1 *= altitude_blend_factor;
+ //if (alpha1 < 0.001f)
+ //{
+ // discard;
+ //}
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
+ // 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;
+ // And smooth
+ alpha2 = 1. - alpha2;
+ alpha2 = 1. - alpha2 * alpha2;
- // Combine
- vec4 color;
- color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color *= 2.;
+ // Combine
+ vec4 color;
+ color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
+ color.rgb *= 2.;
+ color.rgb = scaleSoftClip(color.rgb);
- /// Gamma correct for WL (soft clip effect).
- frag_color.rgb = scaleSoftClip(color.rgb);
- frag_color.a = alpha1;
+ /// Gamma correct for WL (soft clip effect).
+ frag_color = vec4(color.rgb, alpha1);
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index c1dd45cd67..97ffa9feef 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLCloudsV.glsl
+ * @file class2\wl\cloudsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,17 +36,21 @@ ATTRIBUTE vec2 texcoord0;
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 float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
-uniform vec4 ambient;
+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;
@@ -57,128 +61,128 @@ uniform float density_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
uniform float cloud_scale;
+// NOTE: Keep these in sync!
+// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
+// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+// indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl
+// indra\newview\lllegacyatmospherics.cpp
+// indra\newview\llsettingsvo.cpp
void main()
{
-
// World / view / projection
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
+ // Texture coords
+ // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+ vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y); // See: LLSettingsVOSky::applySpecial
+
+ vary_texcoord0.xy -= 0.5;
+ vary_texcoord0.xy /= 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.;
// Get relative position
- vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
+ vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ // fade clouds beyond a certain point so the bottom of the sky dome doesn't look silly at high altitude
+ altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
- // Set altitude
- if (P.y > 0.)
+ // Adj position vector to clamp altitude
+ if (rel_pos.y > 0.)
{
- P *= (max_y / P.y);
+ rel_pos *= (max_y / rel_pos.y);
}
- else
+ if (rel_pos.y < 0.)
{
- P *= (-32000. / P.y);
+ rel_pos *= (-32000. / rel_pos.y);
}
// Can normalize then
- vec3 Pn = normalize(P);
- float Plen = length(P);
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 temp1 = vec4(0.);
- vec4 temp2 = vec4(0.);
- vec4 blue_weight;
- vec4 haze_weight;
vec4 sunlight = sunlight_color;
vec4 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 + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- temp1 = blue_density + haze_density;
- blue_weight = blue_density / temp1;
- haze_weight = haze_density / temp1;
+ vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
+ vec4 blue_weight = blue_density / combined_haze;
+ vec4 haze_weight = haze_density / combined_haze;
- // Compute sunlight from P & lightnorm (for long rays like sky)
- temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
+ // 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);
+ sunlight *= exp(-light_atten * off_axis);
// Distance
- temp2.z = Plen * density_multiplier;
+ float density_dist = rel_pos_len * density_multiplier;
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
// compiler gets confused.
- temp1 = exp(-temp1 * temp2.z);
-
+ combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
- temp2.x = dot(Pn, lightnorm.xyz);
- temp2.x = 1. - temp2.x;
- // temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .001);
+ float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ // 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)
- temp2.x *= glow.x;
+ haze_glow *= glow.x;
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
+ haze_glow = pow(haze_glow, glow.z);
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
+ haze_glow *= sun_moon_glow_factor;
+
// Add "minimum anti-solar illumination"
- temp2.x += .25;
+ // 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);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
+ vec4 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 = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
- );
+ vec4 additiveColorBelowCloud =
+ (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
-
- sunlight = sunlight_color;
- temp2.y = max(0., lightnorm.y * 2.);
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
+ sunlight = sunlight_color; // SL-14707 reset color -- Clouds are unusually dim in EEP
+ off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
+ sunlight *= exp(-light_atten * off_axis);
// Cloud color out
- vary_CloudColorSun = (sunlight * temp2.x) * cloud_color;
+ vary_CloudColorSun = (sunlight * haze_glow) * cloud_color;
vary_CloudColorAmbient = tmpAmbient * cloud_color;
// Attenuate cloud color by atmosphere
- temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
- vary_CloudColorSun *= temp1;
- vary_CloudColorAmbient *= temp1;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1);
+ 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);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
- // Texture coords
- vary_texcoord0 = texcoord0;
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= 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.;
-
// Combine these to minimize register use
vary_CloudColorAmbient += oHazeColorBelowCloud;
@@ -187,4 +191,3 @@ void main()
// END CLOUDS
}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 478373d729..68db7fcbb1 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
@@ -1,5 +1,5 @@
/**
- * @file gammaF.glsl
+ * @file class2\wl\gammaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,23 +22,37 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
-
-uniform vec4 gamma;
+uniform float gamma;
+uniform int no_atmo;
vec3 getAtmosAttenuation();
+vec3 getAdditiveColor();
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
+vec3 scaleSoftClipFrag(vec3 light)
+{
+ 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 scaleSoftClip(vec3 light)
+{
+ return scaleSoftClipFrag(light);
+}
- return light;
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)
+{
+ //return mix(scaleSoftClipFrag(light.rgb), add, atten);
+ return scaleSoftClipFrag(light.rgb);
}
-vec3 fullbrightScaleSoftClip(vec3 light) {
- return mix(scaleSoftClip(light.rgb), light.rgb, getAtmosAttenuation());
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index e2a2367626..7146349453 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
@@ -1,5 +1,5 @@
/**
- * @file WLSkyF.glsl
+ * @file class2/windlight/skyF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -35,17 +35,8 @@ out vec4 frag_color;
VARYING vec4 vary_HazeColor;
-uniform sampler2D cloud_noise_texture;
-uniform vec4 gamma;
-
/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light) {
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, gamma.xxx);
-
- return light;
-}
+vec3 scaleSoftClip(vec3 light);
void main()
{
@@ -56,8 +47,7 @@ void main()
vec4 color;
color = vary_HazeColor;
- color *= 2.;
-
+ color.rgb *= 2.;
/// Gamma correct for WL (soft clip effect).
frag_color.rgb = scaleSoftClip(color.rgb);
frag_color.a = 1.0;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 3788ddaf2d..a0a33b8642 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
@@ -1,28 +1,28 @@
-/**
- * @file WLSkyV.glsl
+/**
+ * @file class2\wl\skyV.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;
@@ -37,120 +37,113 @@ VARYING vec4 vary_HazeColor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 ambient;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+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 vec4 glow;
+uniform float sun_moon_glow_factor;
uniform vec4 cloud_color;
void main()
{
+ // World / view / projection
+ vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Get relative position
- vec3 P = position.xyz - camPosLocal.xyz + vec3(0,50,0);
- //vec3 P = position.xyz + vec3(0,50,0);
-
- // Set altitude
- if (P.y > 0.)
- {
- P *= (max_y / P.y);
- }
- else
- {
- P *= (-32000. / P.y);
- }
-
- // Can normalize then
- vec3 Pn = normalize(P);
- float Plen = length(P);
-
- // Initialize temp variables
- vec4 temp1 = vec4(0.);
- vec4 temp2 = vec4(0.);
- vec4 blue_weight;
- vec4 haze_weight;
- vec4 sunlight = sunlight_color;
- vec4 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);
-
- // Calculate relative weights
- temp1 = blue_density + haze_density;
- blue_weight = blue_density / temp1;
- haze_weight = haze_density / temp1;
-
- // Compute sunlight from P & lightnorm (for long rays like sky)
- temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y );
- temp2.y = 1. / temp2.y;
- sunlight *= exp( - light_atten * temp2.y);
-
- // Distance
- temp2.z = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati
- // compiler gets confused.
- temp1 = exp(-temp1 * temp2.z);
-
-
- // Compute haze glow
- temp2.x = dot(Pn, lightnorm.xyz);
- temp2.x = 1. - temp2.x;
- // temp2.x is 0 at the sun and increases away from sun
- temp2.x = max(temp2.x, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.x *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.x = pow(temp2.x, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- temp2.x += .25;
-
-
- // Haze color above cloud
- vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + ambient)
- );
-
-
- // Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
-
- // Haze color below cloud
- vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient)
- + (haze_horizon * haze_weight) * (sunlight * temp2.x + tmpAmbient)
- );
-
- // Final atmosphere additive
- vary_HazeColor *= (1. - temp1);
-
- // Attenuate cloud color by atmosphere
- temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds
-
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1));
-
- // won't compile on mac without this being set
- //vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
-}
+ gl_Position = pos;
+
+ // Get relative position
+ vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
+
+ // Adj position vector to clamp altitude
+ if (rel_pos.y > 0.)
+ {
+ rel_pos *= (max_y / rel_pos.y);
+ }
+ if (rel_pos.y < 0.)
+ {
+ rel_pos *= (-32000. / rel_pos.y);
+ }
+
+ // Can normalize then
+ vec3 rel_pos_norm = normalize(rel_pos);
+
+ float rel_pos_len = length(rel_pos);
+
+ // Initialize temp variables
+ vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
+ vec4 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);
+
+ // 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;
+ // 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);
+ sunlight *= exp(-light_atten * off_axis);
+
+ // Distance
+ float density_dist = rel_pos_len * density_multiplier;
+
+ // Transparency (-> combined_haze)
+ // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
+ // compiler gets confused.
+ combined_haze = exp(-combined_haze * density_dist);
+
+ // Compute haze glow
+ float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ // 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"
+ // 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 =
+ (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;
+
+ // Dim sunlight by cloud shadow percentage
+ sunlight *= max(0.0, (1. - cloud_shadow));
+
+ // Haze color below cloud
+ vec4 additiveColorBelowCloud =
+ (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+
+ // Attenuate cloud color by atmosphere
+ combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
+
+ // At horizon, blend high altitude sky color towards the darker color below the clouds
+ color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
+
+ // Haze color above cloud
+ vary_HazeColor = color;
+}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index 8a8e4cb0f6..b53a2e237f 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
@@ -1,5 +1,5 @@
/**
- * @file transportF.glsl
+ * @file class2\wl\transportF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -30,24 +30,33 @@
vec3 getAdditiveColor();
vec3 getAtmosAttenuation();
-uniform sampler2D cloudMap;
-uniform vec4 cloud_pos_density1;
+uniform int no_atmo;
-vec3 atmosTransport(vec3 light) {
- light *= getAtmosAttenuation().r;
- light += getAdditiveColor() * 2.0;
+vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ light *= atten.r;
+ light += additive * 2.0;
return light;
}
-vec3 fullbrightAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
-
- return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+vec3 atmosTransport(vec3 light)
+{
+ return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
-vec3 fullbrightShinyAtmosTransport(vec3 light) {
- float brightness = dot(light.rgb, vec3(0.33333));
+vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
+{
+ float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
+ return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
+}
- return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
+vec3 fullbrightAtmosTransport(vec3 light)
+{
+ return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
}
+vec3 fullbrightShinyAtmosTransport(vec3 light)
+{
+ float brightness = dot(light.rgb, vec3(0.33333));
+ return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness);
+}
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
index 721054b5ad..df9704ec25 100644
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
@@ -33,7 +33,7 @@ ATTRIBUTE vec4 clothing;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
@@ -127,7 +127,7 @@ void main()
calcAtmospherics(pos.xyz);
- vec4 col = calcLighting(pos.xyz, norm, color, vec4(0.0));
+ 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
new file mode 100644
index 0000000000..d973326f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
@@ -0,0 +1,44 @@
+/**
+ * @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
new file mode 100644
index 0000000000..1a655e6467
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
@@ -0,0 +1,49 @@
+/**
+ * @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/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
index 587f3d5a94..48eefc7a73 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file srgb.glsl
+ * @file avatarShadowF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,24 +23,30 @@
* $/LicenseInfo$
*/
-vec3 srgb_to_linear(vec3 cs)
-{
- vec3 low_range = cs / vec3(12.92);
- vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+/*[EXTRA_CODE_HERE]*/
- bvec3 lte = lessThanEqual(cs,vec3(0.04045));
- return mix(high_range, low_range, lte);
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
-}
+uniform sampler2D diffuseMap;
-vec3 linear_to_srgb(vec3 cl)
-{
- cl = clamp(cl, vec3(0), vec3(1));
- vec3 low_range = cl * 12.92;
- vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
- bvec3 lt = lessThan(cl,vec3(0.0031308));
- return mix(high_range, low_range, lt);
+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
new file mode 100644
index 0000000000..164b355f20
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
@@ -0,0 +1,68 @@
+/**
+ * @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
new file mode 100644
index 0000000000..32210f60dc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
@@ -0,0 +1,119 @@
+/**
+ * @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
new file mode 100644
index 0000000000..effb070f93
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
@@ -0,0 +1,63 @@
+/**
+ * @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
new file mode 100644
index 0000000000..e40d7e7c75
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
@@ -0,0 +1,166 @@
+/**
+ * @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
new file mode 100644
index 0000000000..71e422ddf0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
@@ -0,0 +1,70 @@
+/**
+ * @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
new file mode 100644
index 0000000000..e27bbce094
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
@@ -0,0 +1,79 @@
+/**
+ * @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
new file mode 100644
index 0000000000..cdaff4b09f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
@@ -0,0 +1,202 @@
+/**
+ * @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/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
new file mode 100644
index 0000000000..34d26cddea
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
@@ -0,0 +1,70 @@
+/**
+ * @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
new file mode 100644
index 0000000000..337c8a50fe
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
@@ -0,0 +1,40 @@
+/**
+ * @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
new file mode 100644
index 0000000000..d5d91c88f0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
@@ -0,0 +1,111 @@
+/**
+ * @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/genSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
new file mode 100644
index 0000000000..b466883dc7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file genSkyShV.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;
+
+void main()
+{
+ // pass through untransformed fullscreen pos
+ gl_Position = vec4(position.xyz, 1.0);
+ vary_frag = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
new file mode 100644
index 0000000000..33c5667cae
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
@@ -0,0 +1,44 @@
+/**
+ * @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/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
new file mode 100644
index 0000000000..9d62b9d180
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -0,0 +1,291 @@
+/**
+ * @file multiSpotLightF.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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
+uniform sampler2DRect lightMap;
+uniform sampler2D noiseMap;
+uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
+
+uniform mat4 proj_mat; //screen space to light space
+uniform float proj_near; //near clip for projection
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform vec3 proj_n;
+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_ambient_lod;
+uniform float proj_ambiance;
+uniform float near_clip;
+uniform float far_clip;
+
+uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
+uniform float sun_wash;
+uniform int proj_shadow_idx;
+uniform float shadow_fade;
+
+uniform vec3 center;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+
+VARYING vec4 vary_fragcoord;
+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;
+}
+
+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);
+
+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)
+ {
+ 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;
+ 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;
+ 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);
+
+ 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)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
+
+ 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;
+
+ 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)
+ {
+ 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));
+
+ 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 (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)
+ {
+ 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;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, 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);
+
+ //output linear space color as gamma correction happens down stream
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
new file mode 100644
index 0000000000..ca9ce3a2e1
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file pointShadowBlur.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 samplerCube cube_map;
+
+in vec3 to_vec;
+
+out vec4 fragColor;
+
+void main()
+{
+ vec4 vcol = texture(cube_map, to_vec);
+ fragColor = vec4(vcol.rgb, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
new file mode 100644
index 0000000000..c8991f7a18
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @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/shVisV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
new file mode 100644
index 0000000000..8f32dfde79
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
@@ -0,0 +1,33 @@
+/**
+ * @file class3/deferred/shVisV.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$
+ */
+ATTRIBUTE vec3 position;
+VARYING vec4 vary_pos;
+
+void main()
+{
+ // Output
+ vary_pos = vec4(position, 1);
+ gl_Position = vary_pos;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
new file mode 100644
index 0000000000..345c07a354
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
@@ -0,0 +1,58 @@
+/**
+ * @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
new file mode 100644
index 0000000000..af1461c297
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
@@ -0,0 +1,66 @@
+/**
+ * @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
new file mode 100644
index 0000000000..50f1ffd626
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
@@ -0,0 +1,74 @@
+/**
+ * @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
new file mode 100644
index 0000000000..6a646f5e9e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @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/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
new file mode 100644
index 0000000000..db8c75fb8a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
@@ -0,0 +1,50 @@
+/**
+ * @file class3/deferred/shadowCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&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_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+#if !defined(DEPTH_CLAMP)
+VARYING vec4 post_pos;
+#endif
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+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
+ gl_Position = pos;
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
new file mode 100644
index 0000000000..3350267130
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
@@ -0,0 +1,49 @@
+/**
+ * @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
new file mode 100644
index 0000000000..2f69a353e8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
@@ -0,0 +1,157 @@
+/**
+ * @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
new file mode 100644
index 0000000000..6577fe0ecf
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
@@ -0,0 +1,62 @@
+/**
+ * @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
new file mode 100644
index 0000000000..a0b082ed7c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
@@ -0,0 +1,126 @@
+/**
+ * @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/skyV.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
new file mode 100644
index 0000000000..2eb222ada4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file class3/deferred/skyV.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;
+
+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;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
new file mode 100644
index 0000000000..7ed9e7b4fc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -0,0 +1,177 @@
+/**
+ * @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
+
+/*[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 lightMap;
+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;
+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;
+
+uniform sampler2D sh_input_r;
+uniform sampler2D sh_input_g;
+uniform sampler2D sh_input_b;
+
+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);
+
+vec3 ColorFromRadiance(vec3 radiance);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+vec4 getPosition(vec2 pos_screen);
+vec3 getNorm(vec2 pos_screen);
+
+#ifdef WATER_FOG
+vec4 applyWaterFogView(vec3 pos, vec4 color);
+#endif
+
+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);
+ float envIntensity = norm.z;
+ norm.xyz = getNorm(tc);
+
+ float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+
+ vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
+ diffuse.rgb = srgb_to_linear(diffuse.rgb);
+
+ vec3 col;
+ 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;
+
+ float scol = max(scol_ambocc.r, diffuse.a);
+
+ float ambocc = scol_ambocc.g;
+
+ 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));
+
+ 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 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
+ vec3 atmo_color = ColorFromRadiance(radiance);
+
+ col = atmo_color + indirect;
+ col *= transmittance;
+ col *= diffuse.rgb;
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ 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;
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
+ bloom = dot(spec_contrib, spec_contrib);
+ col += spec_contrib;
+ }
+
+ col = mix(col, diffuse.rgb, diffuse.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);
+ }
+
+ /*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
+ }
+
+ //output linear since gamma correction happens down stream
+ frag_color.rgb = col;
+ frag_color.a = bloom;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
new file mode 100644
index 0000000000..9d872b8df8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file class3/deferred/softenLightV.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$
+ */
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
+
+uniform mat4 modelview_projection_matrix;
+uniform vec2 screen_res;
+
+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;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
new file mode 100644
index 0000000000..56b0f4e5ce
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -0,0 +1,287 @@
+/**
+ * @file spotLightF.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]*/
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+uniform sampler2DRect specularRect;
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
+uniform sampler2DRect lightMap;
+uniform sampler2D noiseMap;
+uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
+
+uniform mat4 proj_mat; //screen space to light space
+uniform float proj_near; //near clip for projection
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform vec3 proj_n;
+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_ambient_lod;
+uniform float proj_ambiance;
+uniform float near_clip;
+uniform float far_clip;
+
+uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
+uniform float sun_wash;
+uniform int proj_shadow_idx;
+uniform float shadow_fade;
+
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+
+VARYING vec3 trans_center;
+VARYING vec4 vary_fragcoord;
+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;
+}
+
+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);
+
+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)
+ {
+ 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;
+ 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;
+
+ 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);
+
+ 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)
+ {
+ float amb_da = proj_ambiance;
+ float lit = 0.0;
+
+ if (da > 0.0)
+ {
+ lit = da * dist_atten * noise;
+
+ 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;
+
+ 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(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)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ }
+ }
+
+
+ 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)
+ {
+ 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;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ col += color.rgb * texture2DLodSpecular(projectionMap, 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));
+
+ frag_color.rgb = col;
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
new file mode 100644
index 0000000000..112b498c90
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
@@ -0,0 +1,57 @@
+/**
+ * @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
new file mode 100644
index 0000000000..342a2ff3ed
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
@@ -0,0 +1,61 @@
+/**
+ * @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/sunLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
new file mode 100644
index 0000000000..bc5eb5181d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
@@ -0,0 +1,41 @@
+/**
+ * @file sunLightV.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_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_fragcoord;
+
+uniform vec2 screen_res;
+
+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;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
new file mode 100644
index 0000000000..41673d1669
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
@@ -0,0 +1,59 @@
+/**
+ * @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
new file mode 100644
index 0000000000..15e769ac10
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @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/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
new file mode 100644
index 0000000000..540226e672
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
@@ -0,0 +1,115 @@
+/**
+ * @file underWaterF.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_data[3];
+#else
+#define frag_data gl_FragData
+#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 waterFogDensity;
+uniform float waterFogKS;
+uniform vec2 screenRes;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+
+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;
+}
+
+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_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
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
new file mode 100644
index 0000000000..c65cf48c67
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
@@ -0,0 +1,174 @@
+/**
+ * @file 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[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+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
+
+//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));
+ 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;
+
+
+ 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.99999);
+
+ color.rgb *= 2.0f;
+ color.rgb = scaleSoftClip(color.rgb);
+
+ vec4 pos = vary_position;
+
+ color.rgb += spec * specular;
+ color.a = spec * sunAngle2;
+
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
+
+ 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/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
new file mode 100644
index 0000000000..02000d90ca
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
@@ -0,0 +1,95 @@
+/**
+ * @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/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
new file mode 100644
index 0000000000..30ad493331
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file class3\lighting\lightV.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$
+ */
+
+
+
+// All lights, no specular highlights
+vec3 atmosAmbient();
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
+float getAmbientClamp();
+
+vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
+{
+ vec4 c = sumLights(pos, norm, color);
+
+#if !defined(AMBIENT_KILL)
+ c.rgb += atmosAmbient() * color.rgb * getAmbientClamp();
+#endif
+
+ return c;
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
index e043ac873e..c1aee69c30 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class3\lighting\sumLightsSpecularV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,16 +26,16 @@
float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da);
vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol);
-vec3 atmosAmbient(vec3 light);
+vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 atmosGetDiffuseSunlightColor();
vec3 scaleDownLight(vec3 light);
uniform vec4 light_position[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol)
+vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
@@ -55,8 +55,8 @@ vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
- col.rgb += atmosAmbient(baseCol.rgb);
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0));
+ col.rgb += atmosAmbient();
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz,atmosGetDiffuseSunlightColor(), 1.0));
col.rgb = min(col.rgb*color.rgb, 1.0);
specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index dadff40933..4b663dd5b2 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
@@ -1,5 +1,5 @@
/**
- * @file sumLightsV.glsl
+ * @file class3\lighting\sumLightsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -25,37 +25,40 @@
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
+uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
+vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
{
vec4 col = vec4(0.0, 0.0, 0.0, color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
// Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].z);
+ col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
+ col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
+ col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
+ col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
+ col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
col.rgb += light_diffuse[1].rgb*calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb = scaleDownLight(col.rgb);
+ col.rgb = scaleDownLight(col.rgb);
+
+#if defined(LOCAL_LIGHT_KILL)
+ col.rgb = vec3(0);
+#endif
// Add windlight lights
+#if !defined(SUNLIGHT_KILL)
col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
- col.rgb += atmosAmbient(baseLight.rgb);
+#endif
col.rgb = min(col.rgb*color.rgb, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
new file mode 100644
index 0000000000..c6ea3ec9d4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
@@ -0,0 +1,73 @@
+/**
+ * @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
new file mode 100644
index 0000000000..65bb00b1f6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @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
new file mode 100644
index 0000000000..2b70ba76dc
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @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
new file mode 100644
index 0000000000..b76192d73f
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
@@ -0,0 +1,51 @@
+/**
+ * @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
new file mode 100644
index 0000000000..545a32a227
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
@@ -0,0 +1,68 @@
+/**
+ * @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 d8bbf69b38..8ef04d8e1f 100644
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt
@@ -1,3 +1,9 @@
+Class 3 is highest quality / lowest performance
+Class 2 is medium quality / medium performance
+Class 1 is lowest quality / highest performance
+
+Shaders WILL fall back to "lower" classes for functionality.
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
main() - avatar/avatarV.glsl
@@ -7,7 +13,6 @@ avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -28,7 +33,6 @@ avatar/eyeballV.glsl - gAvatarEyeballProgram
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
avatar/eyeballF.glsl - gAvatarEyeballProgram
main() - avatar/eyeballF.glsl
@@ -53,7 +57,6 @@ environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -120,7 +123,6 @@ objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -143,7 +145,6 @@ objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram
sumLights() - lighting/sumLightsV.glsl
calcDirectionalLight() - lighting/lightFuncV.glsl
calcPointLight() - lighting/lightFuncV.glsl
- scaleDownLight() - windlight/atmosphericsHelpersV.glsl
atmosAmbient() - windlight/atmosphericsHelpersV.glsl
atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index 3e7fccbd5f..eb2cd356d9 100644
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -34,8 +34,6 @@
<!--Default for now-->
<RenderVolumeLODFactor value="2.0"/>
<!--NO SHADERS-->
- <VertexShaderEnable value="TRUE"/>
- <!--NO SHADERS-->
<WindLightUseAtmosShaders value="TRUE"/>
<!--Deferred Shading-->
<RenderDeferred value="TRUE"/>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e99b94f150..e6ee458719 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
@@ -98,6 +99,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -129,6 +131,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -159,6 +162,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -189,6 +193,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -219,6 +224,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -249,6 +255,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -279,6 +286,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -309,6 +317,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -320,6 +329,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -375,6 +385,7 @@ WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderUseAdvancedAtmospherics 0 0
//
// No Vertex Shaders available
@@ -388,6 +399,7 @@ WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderUseAdvancedAtmospherics 0 0
//
// GL_ARB_map_buffer_range exists
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 801a622e93..bc836a99ca 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
@@ -97,6 +98,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -128,6 +130,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -158,6 +161,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -188,6 +192,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -217,6 +222,7 @@ RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
@@ -248,6 +254,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -278,6 +285,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -308,6 +316,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -319,6 +328,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -373,6 +383,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -386,6 +397,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -413,6 +425,7 @@ RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 1f891ee4d7..68202a571f 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -66,6 +66,7 @@ RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
@@ -98,6 +99,7 @@ VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -129,6 +131,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -159,6 +162,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -189,6 +193,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -219,6 +224,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -249,6 +255,7 @@ VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -280,6 +287,7 @@ WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
+RenderUseAdvancedAtmospherics 1 0
WLSkyDetail 1 48
RenderFSAASamples 1 2
@@ -309,6 +317,7 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
RenderDeferredSSAO 1 1
+RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -320,6 +329,7 @@ RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderUseAdvancedAtmospherics 1 0
//
// Class 0 Hardware (just old)
@@ -368,6 +378,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -381,6 +392,7 @@ VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
@@ -407,6 +419,7 @@ RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
+RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
//
diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icns
index e15e34140d..a30b51b67a 100644
--- a/indra/newview/icons/release/secondlife.icns
+++ b/indra/newview/icons/release/secondlife.icns
Binary files differ
diff --git a/indra/newview/icons/release/secondlife.ico b/indra/newview/icons/release/secondlife.ico
index 28bf1e7664..93d4fa54ba 100644
--- a/indra/newview/icons/release/secondlife.ico
+++ b/indra/newview/icons/release/secondlife.ico
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png
index 4c9544f498..2f21c1c7fc 100644
--- a/indra/newview/icons/release/secondlife_128.png
+++ b/indra/newview/icons/release/secondlife_128.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png
index bb3168b8be..68f1427309 100644
--- a/indra/newview/icons/release/secondlife_16.png
+++ b/indra/newview/icons/release/secondlife_16.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_256.BMP b/indra/newview/icons/release/secondlife_256.BMP
index 74deedd7d3..dba2636803 100644
--- a/indra/newview/icons/release/secondlife_256.BMP
+++ b/indra/newview/icons/release/secondlife_256.BMP
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png
index bece338a90..8f324910e7 100644
--- a/indra/newview/icons/release/secondlife_256.png
+++ b/indra/newview/icons/release/secondlife_256.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png
index 736359c147..2b7cdef03d 100644
--- a/indra/newview/icons/release/secondlife_32.png
+++ b/indra/newview/icons/release/secondlife_32.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png
index 07d39ae585..c2ef372dd7 100644
--- a/indra/newview/icons/release/secondlife_48.png
+++ b/indra/newview/icons/release/secondlife_48.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.png
index 53d1643f45..d8a0c2924d 100644
--- a/indra/newview/icons/release/secondlife_512.png
+++ b/indra/newview/icons/release/secondlife_512.png
Binary files differ
diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP
index 09df573870..dba2636803 100644
--- a/indra/newview/installers/windows/install_icon.BMP
+++ b/indra/newview/installers/windows/install_icon.BMP
Binary files differ
diff --git a/indra/newview/installers/windows/install_icon.ico b/indra/newview/installers/windows/install_icon.ico
index efe6c4f323..93d4fa54ba 100644
--- a/indra/newview/installers/windows/install_icon.ico
+++ b/indra/newview/installers/windows/install_icon.ico
Binary files differ
diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP
index 562b56676a..dba2636803 100644
--- a/indra/newview/installers/windows/uninstall_icon.BMP
+++ b/indra/newview/installers/windows/uninstall_icon.BMP
Binary files differ
diff --git a/indra/newview/installers/windows/uninstall_icon.ico b/indra/newview/installers/windows/uninstall_icon.ico
index 05e1546860..93d4fa54ba 100644
--- a/indra/newview/installers/windows/uninstall_icon.ico
+++ b/indra/newview/installers/windows/uninstall_icon.ico
Binary files differ
diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt
index e01b9e4bc6..cb8d1af535 100644
--- a/indra/newview/linux_tools/client-readme.txt
+++ b/indra/newview/linux_tools/client-readme.txt
@@ -187,8 +187,8 @@ The 'secondlife' script which launches Second Life contains some
configuration options for advanced troubleshooters.
* AUDIO - Edit the 'secondlife' script and you will see these audio
- options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMOD_ESD, LL_BAD_FMOD_OSS, and
- LL_BAD_FMOD_ALSA. Second Life tries to use OpenAL, ESD, OSS, then ALSA
+ options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER.
+ Second Life tries to use OpenAL, FMODSTUDIO (PULSEAUDIO, ALSA)
audio drivers in this order; you may uncomment the corresponding LL_BAD_*
option to skip an audio driver which you believe may be causing you trouble.
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index c23401d5a6..eb3ead433b 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -4,17 +4,15 @@
## These options are for self-assisted troubleshooting during this beta
## testing phase; you should not usually need to touch them.
-## - Avoids using any FMOD Ex audio driver.
-#export LL_BAD_FMODEX_DRIVER=x
+## - Avoids using any FMOD STUDIO audio driver.
+#export LL_BAD_FMODSTUDIO_DRIVER=x
## - Avoids using any OpenAL audio driver.
#export LL_BAD_OPENAL_DRIVER=x
-## - Avoids using the FMOD Ex PulseAudio audio driver.
+## - Avoids using the FMOD Studio or FMOD Ex PulseAudio audio driver.
#export LL_BAD_FMOD_PULSEAUDIO=x
-## - Avoids using the FMOD or FMOD Ex ALSA audio driver.
+## - Avoids using the FMOD Studio or FMOD Ex ALSA audio driver.
#export LL_BAD_FMOD_ALSA=x
-## - Avoids using the FMOD or FMOD Ex OSS audio driver.
-#export LL_BAD_FMOD_OSS=x
## - Avoids the optional OpenGL extensions which have proven most problematic
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 1dddf52961..e09527a34b 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -48,7 +48,7 @@ LLAccountingCostManager::LLAccountingCostManager()
void LLAccountingCostManager::accountingCostCoro(std::string url,
eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
{
- LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName()
+ LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::getName()
<< " with url '" << url << LL_ENDL;
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
@@ -158,7 +158,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
}
catch (...)
{
- LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName()
+ LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
<< "('" << url << "')"));
throw;
}
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 55e1d19f05..d133c6437b 100644
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -30,12 +30,6 @@
#include "llhandle.h"
#include "llaccountingcost.h"
-#include "httpcommon.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-#include "httprequest.h"
-#include "httpheaders.h"
-#include "httpoptions.h"
//===============================================================================
// An interface class for panels which display the parcel accounting information.
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 31b8b90518..3c50493d79 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -32,6 +32,7 @@
#include "pipeline.h"
#include "llagentaccess.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llagentlistener.h"
#include "llagentwearables.h"
@@ -43,7 +44,6 @@
#include "llchicletbar.h"
#include "llconsole.h"
#include "lldonotdisturbnotificationstorage.h"
-#include "llenvmanager.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterimcontainer.h"
@@ -137,6 +137,10 @@ public:
EStatus getStatus() const {return mStatus;};
void setStatus(EStatus pStatus) {mStatus = pStatus;};
+ static std::map<S32, std::string> sTeleportStatusName;
+ static const std::string& statusName(EStatus status);
+ virtual void toOstream(std::ostream& os) const;
+
virtual bool canRestartTeleport();
virtual void startTeleport() = 0;
@@ -148,12 +152,19 @@ private:
EStatus mStatus;
};
+std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending, "kPending" },
+ { kStarted, "kStarted" },
+ { kFailed, "kFailed" },
+ { kRestartPending, "kRestartPending"} };
+
class LLTeleportRequestViaLandmark : public LLTeleportRequest
{
public:
LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
virtual ~LLTeleportRequestViaLandmark();
+ virtual void toOstream(std::ostream& os) const;
+
virtual bool canRestartTeleport();
virtual void startTeleport();
@@ -172,6 +183,8 @@ public:
LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
virtual ~LLTeleportRequestViaLure();
+ virtual void toOstream(std::ostream& os) const;
+
virtual bool canRestartTeleport();
virtual void startTeleport();
@@ -189,6 +202,8 @@ public:
LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
virtual ~LLTeleportRequestViaLocation();
+ virtual void toOstream(std::ostream& os) const;
+
virtual bool canRestartTeleport();
virtual void startTeleport();
@@ -208,6 +223,8 @@ public:
LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
virtual ~LLTeleportRequestViaLocationLookAt();
+ virtual void toOstream(std::ostream& os) const;
+
virtual bool canRestartTeleport();
virtual void startTeleport();
@@ -370,6 +387,7 @@ LLAgent::LLAgent() :
mTeleportFinishedSlot(),
mTeleportFailedSlot(),
mIsMaturityRatingChangingDuringTeleport(false),
+ mTPNeedsNeabyChatSeparator(false),
mMaturityRatingChange(0U),
mIsDoSendMaturityPreferenceToServer(false),
mMaturityPreferenceRequestId(0U),
@@ -383,6 +401,7 @@ LLAgent::LLAgent() :
mAgentOriginGlobal(),
mPositionGlobal(),
+ mLastTestGlobal(),
mDistanceTraveled(0.F),
mLastPositionGlobal(LLVector3d::zero),
@@ -491,6 +510,8 @@ void LLAgent::init()
void LLAgent::cleanup()
{
mRegionp = NULL;
+ mTeleportRequest = NULL;
+ mTeleportCanceled = NULL;
if (mTeleportFinishedSlot.connected())
{
mTeleportFinishedSlot.disconnect();
@@ -774,7 +795,7 @@ void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
// and it's OK if you're already flying
if (fail_sound)
{
- make_ui_sound("UISndBadKeystroke");
+ make_ui_sound("UISndBadKeystroke");
}
return;
}
@@ -829,6 +850,17 @@ bool LLAgent::enableFlying()
return !sitting;
}
+// static
+bool LLAgent::isSitting()
+{
+ BOOL sitting = FALSE;
+ if (isAgentAvatarValid())
+ {
+ sitting = gAgentAvatarp->isSitting();
+ }
+ return sitting;
+}
+
void LLAgent::standUp()
{
setControlFlags(AGENT_CONTROL_STAND_UP);
@@ -846,6 +878,18 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
return mParcelChangedSignal.connect(cb);
}
+// static
+void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->getRegionID() == region_id)
+ {
+ region->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl();
+ }
+}
+
+
//-----------------------------------------------------------------------------
// setRegion()
//-----------------------------------------------------------------------------
@@ -855,9 +899,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (mRegionp != regionp)
{
- std::string ip = regionp->getHost().getString();
- LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName()
- << " located at " << ip << LL_ENDL;
+ LL_INFOS("AgentLocation","Teleport") << "Moving agent into region: handle " << regionp->getHandle()
+ << " id " << regionp->getRegionID()
+ << " name " << regionp->getName()
+ << " previous region "
+ << (mRegionp ? mRegionp->getRegionID() : LLUUID::null)
+ << LL_ENDL;
if (mRegionp)
{
// We've changed regions, we're now going to change our agent coordinate frame.
@@ -889,10 +936,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl();
}
else
{
- regionp->setCapabilitiesReceivedCallback(boost::bind(&LLViewerRegion::requestSimulatorFeatures, regionp));
+ regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
}
}
@@ -911,6 +959,15 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
// Update all of the regions.
LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
+
+ if (regionp->capabilitiesReceived())
+ {
+ LLAppViewer::instance()->updateNameLookupUrl();
+ }
+ else
+ {
+ regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
+ }
}
// Pass new region along to metrics components that care about this level of detail.
@@ -1085,6 +1142,13 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
pos_agent_d.setVec(pos_agent);
mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
}
+
+ if (((mLastTestGlobal - mPositionGlobal).lengthSquared() > 1.0) && !mOnPositionChanged.empty())
+ { // If the position has changed my more than 1 meter since the last time we triggered.
+ // filters out some noise.
+ mLastTestGlobal = mPositionGlobal;
+ mOnPositionChanged(mFrameAgent.getOrigin(), mPositionGlobal);
+ }
}
//-----------------------------------------------------------------------------
@@ -1125,6 +1189,12 @@ const LLVector3 &LLAgent::getPositionAgent()
return mFrameAgent.getOrigin();
}
+boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot_type fn)
+{
+ return mOnPositionChanged.connect(fn);
+}
+
+
//-----------------------------------------------------------------------------
// getRegionsVisited()
//-----------------------------------------------------------------------------
@@ -2022,6 +2092,14 @@ U8 LLAgent::getRenderState()
//-----------------------------------------------------------------------------
void LLAgent::endAnimationUpdateUI()
{
+ if (LLApp::isExiting()
+ || !gViewerWindow
+ || !gMenuBarView
+ || !gToolBarView
+ || !gStatusBar)
+ {
+ return;
+ }
if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode())
{
// We're already done endAnimationUpdateUI for this transition.
@@ -2598,6 +2676,7 @@ void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
else
{
mMaturityPreferenceNumRetries = 0;
+ LL_WARNS() << "Too many retries for maturity preference" << LL_ENDL;
reportPreferredMaturityError();
}
}
@@ -2649,6 +2728,7 @@ void LLAgent::reportPreferredMaturityError()
mIsMaturityRatingChangingDuringTeleport = false;
if (hasPendingTeleportRequest())
{
+ LL_WARNS("Teleport") << "Teleport failing due to preferred maturity error" << LL_ENDL;
setTeleportState(LLAgent::TELEPORT_NONE);
}
@@ -2984,7 +3064,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO
BOOL LLAgent::canJoinGroups() const
{
- return (S32)mGroups.size() < gMaxAgentGroups;
+ return (S32)mGroups.size() < LLAgentBenefitsMgr::current().getGroupMembershipLimit();
}
LLQuaternion LLAgent::getHeadRotation()
@@ -3744,7 +3824,7 @@ void LLAgent::clearVisualParams(void *data)
// protected
bool LLAgent::teleportCore(bool is_local)
{
- LL_INFOS("Teleport") << "In teleport core!" << LL_ENDL;
+ LL_DEBUGS("Teleport") << "In teleport core" << LL_ENDL;
if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
{
LL_WARNS() << "Attempt to teleport when already teleporting." << LL_ENDL;
@@ -3810,11 +3890,13 @@ bool LLAgent::teleportCore(bool is_local)
add(LLStatViewer::TELEPORT, 1);
if (is_local)
{
+ LL_INFOS("Teleport") << "Setting teleport state to TELEPORT_LOCAL" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
}
else
{
gTeleportDisplay = TRUE;
+ LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_START );
//release geometry from old location
@@ -3853,6 +3935,7 @@ void LLAgent::clearTeleportRequest()
LLVoiceClient::getInstance()->setHidden(FALSE);
}
mTeleportRequest.reset();
+ mTPNeedsNeabyChatSeparator = false;
}
void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
@@ -3861,6 +3944,12 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
mMaturityRatingChange = pMaturityRatingChange;
}
+void LLAgent::sheduleTeleportIM()
+{
+ // is supposed to be called during teleport so we are still waiting for parcel
+ mTPNeedsNeabyChatSeparator = true;
+}
+
bool LLAgent::hasPendingTeleportRequest()
{
return ((mTeleportRequest != NULL) &&
@@ -3881,6 +3970,7 @@ void LLAgent::startTeleportRequest()
if (!isMaturityPreferenceSyncedWithServer())
{
gTeleportDisplay = TRUE;
+ LL_INFOS("Teleport") << "Maturity preference not synced yet, setting teleport state to TELEPORT_PENDING" << LL_ENDL;
setTeleportState(TELEPORT_PENDING);
}
else
@@ -3907,6 +3997,12 @@ void LLAgent::startTeleportRequest()
void LLAgent::handleTeleportFinished()
{
LL_INFOS("Teleport") << "Agent handling teleport finished." << LL_ENDL;
+ if (mTPNeedsNeabyChatSeparator)
+ {
+ // parcel is ready at this point
+ addTPNearbyChatSeparator();
+ mTPNeedsNeabyChatSeparator = false;
+ }
clearTeleportRequest();
mTeleportCanceled.reset();
if (mIsMaturityRatingChangingDuringTeleport)
@@ -3924,10 +4020,19 @@ void LLAgent::handleTeleportFinished()
{
if (mRegionp->capabilitiesReceived())
{
+ LL_DEBUGS("Teleport") << "capabilities have been received for region handle "
+ << mRegionp->getHandle()
+ << " id " << mRegionp->getRegionID()
+ << ", calling onCapabilitiesReceivedAfterTeleport()"
+ << LL_ENDL;
onCapabilitiesReceivedAfterTeleport();
}
else
{
+ LL_DEBUGS("Teleport") << "Capabilities not yet received for region handle "
+ << mRegionp->getHandle()
+ << " id " << mRegionp->getRegionID()
+ << LL_ENDL;
mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
}
}
@@ -3960,11 +4065,61 @@ void LLAgent::handleTeleportFailed()
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
+
+ mTPNeedsNeabyChatSeparator = false;
+}
+
+/*static*/
+void LLAgent::addTPNearbyChatSeparator()
+{
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_region || !agent_parcel)
+ {
+ return;
+ }
+
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ std::string location_name;
+ LLAgentUI::ELocationFormat format = LLAgentUI::LOCATION_FORMAT_NO_MATURITY;
+
+ // Might be better to provide slurl to chat
+ if (!LLAgentUI::buildLocationString(location_name, format))
+ {
+ location_name = "Teleport to new region"; // Shouldn't happen
+ }
+
+ LLChat chat;
+ chat.mFromName = location_name;
+ chat.mMuted = FALSE;
+ chat.mFromID = LLUUID::null;
+ chat.mSourceType = CHAT_SOURCE_TELEPORT;
+ chat.mChatStyle = CHAT_STYLE_TELEPORT_SEP;
+ chat.mText = "";
+
+ LLSD args;
+ args["do_not_log"] = TRUE;
+ nearby_chat->addMessage(chat, true, args);
+ }
}
/*static*/
void LLAgent::onCapabilitiesReceivedAfterTeleport()
{
+ if (gAgent.getRegion())
+ {
+ LL_DEBUGS("Teleport") << "running after capabilities received callback has been triggered, agent region "
+ << gAgent.getRegion()->getHandle()
+ << " id " << gAgent.getRegion()->getRegionID()
+ << " name " << gAgent.getRegion()->getName()
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Teleport") << "called when agent region is null!" << LL_ENDL;
+ }
check_merchant_status();
}
@@ -3978,8 +4133,8 @@ void LLAgent::teleportRequest(
LLViewerRegion* regionp = getRegion();
if (regionp && teleportCore(region_handle == regionp->getHandle()))
{
- LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':"
- << pos_local << LL_ENDL;
+ LL_INFOS("Teleport") << "Sending TeleportLocationRequest: '" << region_handle << "':"
+ << pos_local << LL_ENDL;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("TeleportLocationRequest");
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4010,6 +4165,11 @@ void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
LLViewerRegion *regionp = getRegion();
if(regionp && teleportCore())
{
+ LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
+ << " region id " << regionp->getRegionID()
+ << " requested landmark id " << landmark_asset_id
+ << LL_ENDL;
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
msg->nextBlockFast(_PREHASH_Info);
@@ -4042,6 +4202,11 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
}
+ LL_INFOS("Teleport") << "Sending TeleportLureRequest."
+ << " Current region handle " << regionp->getHandle()
+ << " region id " << regionp->getRegionID()
+ << " lure id " << lure_id
+ << LL_ENDL;
// send the message
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_TeleportLureRequest);
@@ -4064,6 +4229,8 @@ void LLAgent::teleportCancel()
LLViewerRegion* regionp = getRegion();
if(regionp)
{
+ LL_INFOS("Teleport") << "Sending TeleportCancel" << LL_ENDL;
+
// send the message
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("TeleportCancel");
@@ -4076,13 +4243,14 @@ void LLAgent::teleportCancel()
}
clearTeleportRequest();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
- gPipeline.resetVertexBuffers();
+ gPipeline.resetVertexBuffers();
}
void LLAgent::restoreCanceledTeleportRequest()
{
if (mTeleportCanceled != NULL)
{
+ LL_INFOS() << "Restoring canceled teleport request, setting state to TELEPORT_REQUESTED" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
mTeleportRequest = mTeleportCanceled;
mTeleportCanceled.reset();
@@ -4120,7 +4288,6 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
else if(regionp &&
teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
{
- LL_WARNS() << "Using deprecated teleportlocationrequest." << LL_ENDL;
// send the message
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_TeleportLocationRequest);
@@ -4140,6 +4307,14 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
msg->addVector3Fast(_PREHASH_Position, pos);
pos.mV[VX] += 1;
msg->addVector3Fast(_PREHASH_LookAt, pos);
+
+ LL_WARNS("Teleport") << "Sending deprecated(?) TeleportLocationRequest."
+ << " pos_global " << pos_global
+ << " region_x " << region_x
+ << " region_y " << region_y
+ << " region_handle " << region_handle
+ << LL_ENDL;
+
sendReliableMessage();
}
}
@@ -4181,7 +4356,11 @@ void LLAgent::setTeleportState(ETeleportState state)
" for previously failed teleport. Ignore!" << LL_ENDL;
return;
}
- LL_DEBUGS("Teleport") << "Setting teleport state to " << state << " Previous state: " << mTeleportState << LL_ENDL;
+ LL_DEBUGS("Teleport") << "Setting teleport state to "
+ << LLAgent::teleportStateName(state) << "(" << state << ")"
+ << " Previous state: "
+ << teleportStateName(mTeleportState) << "(" << mTeleportState << ")"
+ << LL_ENDL;
mTeleportState = state;
if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
{
@@ -4518,6 +4697,34 @@ void LLAgent::observeFriends()
}
}
+std::map<S32, std::string> LLAgent::sTeleportStateName = { { TELEPORT_NONE, "TELEPORT_NONE" },
+ { TELEPORT_START, "TELEPORT_START" },
+ { TELEPORT_REQUESTED, "TELEPORT_REQUESTED" },
+ { TELEPORT_MOVING, "TELEPORT_MOVING" },
+ { TELEPORT_START_ARRIVAL, "TELEPORT_START_ARRIVAL" },
+ { TELEPORT_ARRIVING, "TELEPORT_ARRIVING" },
+ { TELEPORT_LOCAL, "TELEPORT_LOCAL" },
+ { TELEPORT_PENDING, "TELEPORT_PENDING" } };
+
+const std::string& LLAgent::teleportStateName(S32 state)
+{
+ static std::string invalid_state_str("INVALID");
+ auto iter = LLAgent::sTeleportStateName.find(state);
+ if (iter != LLAgent::sTeleportStateName.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return invalid_state_str;
+ }
+}
+
+const std::string& LLAgent::getTeleportStateName() const
+{
+ return teleportStateName(getTeleportState());
+}
+
void LLAgent::parseTeleportMessages(const std::string& xml_filename)
{
LLXMLNodePtr root;
@@ -4641,40 +4848,70 @@ void LLTeleportRequest::restartTeleport()
llassert(0);
}
+// TODO this enum -> name idiom should be in a common class rather than repeated various places.
+const std::string& LLTeleportRequest::statusName(EStatus status)
+{
+ static std::string invalid_status_str("INVALID");
+ auto iter = LLTeleportRequest::sTeleportStatusName.find(status);
+ if (iter != LLTeleportRequest::sTeleportStatusName.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return invalid_status_str;
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const LLTeleportRequest& req)
+{
+ req.toOstream(os);
+ return os;
+}
+
+void LLTeleportRequest::toOstream(std::ostream& os) const
+{
+ os << "status " << statusName(mStatus) << "(" << mStatus << ")";
+}
+
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLandmark
//-----------------------------------------------------------------------------
-
LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
: LLTeleportRequest(),
mLandmarkId(pLandmarkId)
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created." << LL_ENDL;
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
}
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
{
- LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark" << LL_ENDL;
+ LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
+}
+
+void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
+{
+ os << "landmark " << mLandmarkId << " ";
+ LLTeleportRequest::toOstream(os);
}
bool LLTeleportRequestViaLandmark::canRestartTeleport()
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true" << LL_ENDL;
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true, " << *this << LL_ENDL;
return true;
}
void LLTeleportRequestViaLandmark::startTeleport()
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport" << LL_ENDL;
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport, " << *this << LL_ENDL;
gAgent.doTeleportViaLandmark(getLandmarkId());
}
void LLTeleportRequestViaLandmark::restartTeleport()
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport" << LL_ENDL;
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport, " << *this << LL_ENDL;
gAgent.doTeleportViaLandmark(getLandmarkId());
}
-
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLure
//-----------------------------------------------------------------------------
@@ -4691,6 +4928,12 @@ LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
LL_INFOS("Teleport") << "~LLTeleportRequestViaLure" << LL_ENDL;
}
+void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
+{
+ os << "mIsLureGodLike " << (S32) mIsLureGodLike << " ";
+ LLTeleportRequestViaLandmark::toOstream(os);
+}
+
bool LLTeleportRequestViaLure::canRestartTeleport()
{
// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
@@ -4731,6 +4974,12 @@ LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
LL_INFOS("Teleport") << "~LLTeleportRequestViaLocation" << LL_ENDL;
}
+void LLTeleportRequestViaLocation::toOstream(std::ostream& os) const
+{
+ os << "mPosGlobal " << mPosGlobal << " ";
+ LLTeleportRequest::toOstream(os);
+}
+
bool LLTeleportRequestViaLocation::canRestartTeleport()
{
LL_INFOS("Teleport") << "LLTeleportRequestViaLocation::canRestartTeleport -> true" << LL_ENDL;
@@ -4764,6 +5013,11 @@ LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
LL_INFOS("Teleport") << "~LLTeleportRequestViaLocationLookAt" << LL_ENDL;
}
+void LLTeleportRequestViaLocationLookAt::toOstream(std::ostream& os) const
+{
+ LLTeleportRequestViaLocation::toOstream(os);
+}
+
bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
{
LL_INFOS("Teleport") << "LLTeleportRequestViaLocationLookAt::canRestartTeleport -> true" << LL_ENDL;
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 5ba1083d8e..a792d3e11f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -47,20 +47,15 @@ extern const BOOL ANIMATE;
extern const U8 AGENT_STATE_TYPING; // Typing indication
extern const U8 AGENT_STATE_EDITING; // Set when agent has objects selected
-class LLChat;
class LLViewerRegion;
class LLMotion;
-class LLToolset;
class LLMessageSystem;
class LLPermissions;
class LLHost;
class LLFriendObserver;
-class LLPickInfo;
-class LLViewerObject;
class LLAgentDropGroupViewerNode;
class LLAgentAccess;
class LLSLURL;
-class LLPauseRequestHandle;
class LLUIColor;
class LLTeleportRequest;
@@ -91,8 +86,6 @@ struct LLGroupData
class LLAgentListener;
-class LLAgentImpl;
-
//------------------------------------------------------------------------
// LLAgent
//------------------------------------------------------------------------
@@ -189,6 +182,8 @@ private:
// Position
//--------------------------------------------------------------------
public:
+ typedef boost::signals2::signal<void(const LLVector3 &position_local, const LLVector3d &position_global)> position_signal_t;
+
LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const;
LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const;
const LLVector3d &getPositionGlobal() const;
@@ -196,11 +191,17 @@ public:
// Call once per frame to update position, angles (radians).
void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y);
void setPositionAgent(const LLVector3 &center);
+
+ boost::signals2::connection whenPositionChanged(position_signal_t::slot_type fn);
+
protected:
void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition
private:
mutable LLVector3d mPositionGlobal;
+ position_signal_t mOnPositionChanged;
+ LLVector3d mLastTestGlobal;
+
//--------------------------------------------------------------------
// Velocity
//--------------------------------------------------------------------
@@ -253,6 +254,8 @@ public:
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
private:
+ static void capabilityReceivedCallback(const LLUUID &region_id);
+
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
parcel_changed_signal_t mParcelChangedSignal;
@@ -343,6 +346,7 @@ public:
static void toggleFlying();
static bool enableFlying();
BOOL canFly(); // Does this parcel allow you to fly?
+ static bool isSitting();
//--------------------------------------------------------------------
// Voice
@@ -610,6 +614,10 @@ public:
TELEPORT_PENDING = 7
};
+ static std::map<S32, std::string> sTeleportStateName;
+ static const std::string& teleportStateName(S32);
+ const std::string& getTeleportStateName() const;
+
public:
static void parseTeleportMessages(const std::string& xml_filename);
const void getTeleportSourceSLURL(LLSLURL& slurl) const;
@@ -645,6 +653,7 @@ public:
void restartFailedTeleportRequest();
void clearTeleportRequest();
void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
+ void sheduleTeleportIM();
private:
@@ -661,6 +670,7 @@ private:
boost::signals2::connection mTeleportFailedSlot;
bool mIsMaturityRatingChangingDuringTeleport;
+ bool mTPNeedsNeabyChatSeparator;
U8 mMaturityRatingChange;
bool hasPendingTeleportRequest();
@@ -677,6 +687,7 @@ private:
void handleTeleportFinished();
void handleTeleportFailed();
+ static void addTPNearbyChatSeparator();
static void onCapabilitiesReceivedAfterTeleport();
//--------------------------------------------------------------------
diff --git a/indra/newview/llagentbenefits.cpp b/indra/newview/llagentbenefits.cpp
new file mode 100644
index 0000000000..2d219735a0
--- /dev/null
+++ b/indra/newview/llagentbenefits.cpp
@@ -0,0 +1,236 @@
+/**
+* @file llagentbenefits.cpp
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* 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$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llagentbenefits.h"
+
+LLAgentBenefits::LLAgentBenefits():
+ m_initalized(false),
+ m_animated_object_limit(-1),
+ m_animation_upload_cost(-1),
+ m_attachment_limit(-1),
+ m_group_membership_limit(-1),
+ m_picks_limit(-1),
+ m_sound_upload_cost(-1),
+ m_texture_upload_cost(-1)
+{
+}
+
+LLAgentBenefits::~LLAgentBenefits()
+{
+}
+
+// This could be extended to a template scheme or otherwise modified
+// to support other types, if and when needed. Currently all fields
+// the viewer cares about are integer.
+bool get_required_S32(const LLSD& sd, const LLSD::String& key, S32& value)
+{
+ value = -1;
+ if (sd.has(key))
+ {
+ value = sd[key].asInteger();
+ return true;
+ }
+
+ LL_WARNS("Benefits") << "Missing required benefit field " << key << LL_ENDL;
+ return false;
+}
+
+bool LLAgentBenefits::init(const LLSD& benefits_sd)
+{
+ LL_DEBUGS("Benefits") << "initializing benefits from " << benefits_sd << LL_ENDL;
+
+ if (!get_required_S32(benefits_sd, "animated_object_limit", m_animated_object_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "animation_upload_cost", m_animation_upload_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "attachment_limit", m_attachment_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "create_group_cost", m_create_group_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "group_membership_limit", m_group_membership_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "picks_limit", m_picks_limit))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "sound_upload_cost", m_sound_upload_cost))
+ {
+ return false;
+ }
+ if (!get_required_S32(benefits_sd, "texture_upload_cost", m_texture_upload_cost))
+ {
+ return false;
+ }
+
+ // FIXME PREMIUM - either use this field or get rid of it
+ m_initalized = true;
+ return true;
+}
+
+S32 LLAgentBenefits::getAnimatedObjectLimit() const
+{
+ return m_animated_object_limit;
+}
+
+S32 LLAgentBenefits::getAnimationUploadCost() const
+{
+ return m_animation_upload_cost;
+}
+
+S32 LLAgentBenefits::getAttachmentLimit() const
+{
+ return m_attachment_limit;
+}
+
+S32 LLAgentBenefits::getCreateGroupCost() const
+{
+ return m_create_group_cost;
+}
+
+S32 LLAgentBenefits::getGroupMembershipLimit() const
+{
+ return m_group_membership_limit;
+}
+
+S32 LLAgentBenefits::getPicksLimit() const
+{
+ return m_picks_limit;
+}
+
+S32 LLAgentBenefits::getSoundUploadCost() const
+{
+ return m_sound_upload_cost;
+}
+
+S32 LLAgentBenefits::getTextureUploadCost() const
+{
+ return m_texture_upload_cost;
+}
+
+bool LLAgentBenefits::findUploadCost(LLAssetType::EType& asset_type, S32& cost) const
+{
+ bool succ = false;
+ if (asset_type == LLAssetType::AT_TEXTURE)
+ {
+ cost = getTextureUploadCost();
+ succ = true;
+ }
+ else if (asset_type == LLAssetType::AT_SOUND)
+ {
+ cost = getSoundUploadCost();
+ succ = true;
+ }
+ else if (asset_type == LLAssetType::AT_ANIMATION)
+ {
+ cost = getAnimationUploadCost();
+ succ = true;
+ }
+ return succ;
+}
+
+LLAgentBenefitsMgr::LLAgentBenefitsMgr()
+{
+}
+
+LLAgentBenefitsMgr::~LLAgentBenefitsMgr()
+{
+}
+
+// static
+const LLAgentBenefits& LLAgentBenefitsMgr::current()
+{
+ return instance().mCurrent;
+}
+
+// static
+const LLAgentBenefits& LLAgentBenefitsMgr::get(const std::string& package)
+{
+ if (instance().mPackageMap.find(package) != instance().mPackageMap.end())
+ {
+ return instance().mPackageMap[package];
+ }
+ else
+ {
+ return instance().mDefault;
+ }
+}
+
+// static
+bool LLAgentBenefitsMgr::init(const std::string& package, const LLSD& benefits_sd)
+{
+ LLAgentBenefits benefits;
+ if (!benefits.init(benefits_sd))
+ {
+ LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ instance().mPackageMap[package] = benefits;
+ }
+ return true;
+
+}
+
+// static
+bool LLAgentBenefitsMgr::initCurrent(const std::string& package, const LLSD& benefits_sd)
+{
+ LLAgentBenefits benefits;
+ if (!benefits.init(benefits_sd))
+ {
+ LL_WARNS("Benefits") << "Unable to initialize package " << package << " from sd " << benefits_sd << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ instance().mCurrent = benefits;
+ instance().mCurrentName = package;
+ }
+ return true;
+
+}
+
+// static
+bool LLAgentBenefitsMgr::has(const std::string& package)
+{
+ return instance().mPackageMap.find(package) != instance().mPackageMap.end();
+}
+
+//static
+bool LLAgentBenefitsMgr::isCurrent(const std::string& package)
+{
+ return instance().mCurrentName == package;
+}
diff --git a/indra/newview/llagentbenefits.h b/indra/newview/llagentbenefits.h
new file mode 100644
index 0000000000..48aa6bd869
--- /dev/null
+++ b/indra/newview/llagentbenefits.h
@@ -0,0 +1,88 @@
+/**
+* @file llagentbenefits.h
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* 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$
+*/
+
+#ifndef LL_AGENTBENEFITS_H
+#define LL_AGENTBENEFITS_H
+
+#include "llsingleton.h"
+#include "llsd.h"
+#include "llassettype.h"
+
+class LLAgentBenefits
+{
+public:
+ LLAgentBenefits();
+ ~LLAgentBenefits();
+ LOG_CLASS(LLAgentBenefits);
+
+ bool init(const LLSD& benefits_sd);
+
+ S32 getAnimatedObjectLimit() const;
+ S32 getAnimationUploadCost() const;
+ S32 getAttachmentLimit() const;
+ S32 getCreateGroupCost() const;
+ S32 getGroupMembershipLimit() const;
+ S32 getPicksLimit() const;
+ S32 getSoundUploadCost() const;
+ S32 getTextureUploadCost() const;
+
+ bool findUploadCost(LLAssetType::EType& asset_type, S32& cost) const;
+
+private:
+ S32 m_animated_object_limit;
+ S32 m_animation_upload_cost;
+ S32 m_attachment_limit;
+ S32 m_create_group_cost;
+ S32 m_group_membership_limit;
+ S32 m_picks_limit;
+ S32 m_sound_upload_cost;
+ S32 m_texture_upload_cost;
+
+ bool m_initalized;
+};
+
+class LLAgentBenefitsMgr: public LLSingleton<LLAgentBenefitsMgr>
+{
+ LLSINGLETON(LLAgentBenefitsMgr);
+ ~LLAgentBenefitsMgr();
+ LOG_CLASS(LLAgentBenefitsMgr);
+
+public:
+ static const LLAgentBenefits& current();
+ static const LLAgentBenefits& get(const std::string& package);
+ static bool init(const std::string& package, const LLSD& benefits_sd);
+ static bool initCurrent(const std::string& package, const LLSD& benefits_sd);
+ static bool has(const std::string& package);
+ static bool isCurrent(const std::string& package);
+
+private:
+ std::string mCurrentName;
+ LLAgentBenefits mCurrent;
+ LLAgentBenefits mDefault;
+ std::map<std::string, LLAgentBenefits> mPackageMap;
+};
+
+
+#endif
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 8edb1a5f0b..ed6c3c307f 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -184,6 +184,9 @@ LLAgentCamera::LLAgentCamera() :
clearGeneralKeys();
clearOrbitKeys();
clearPanKeys();
+
+ resetPanDiff();
+ resetOrbitDiff();
}
// Requires gSavedSettings to be initialized.
@@ -205,15 +208,10 @@ void LLAgentCamera::init()
mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
- mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
-
- mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("CameraOffsetRearView");
- mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("CameraOffsetFrontView");
- mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("CameraOffsetGroupView");
+ mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
- mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("FocusOffsetRearView");
- mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("FocusOffsetFrontView");
- mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("FocusOffsetGroupView");
+ mCameraOffsetInitial = gSavedSettings.getControl("CameraOffsetRearView");
+ mFocusOffsetInitial = gSavedSettings.getControl("FocusOffsetRearView");
mCameraCollidePlane.clearVec();
mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
@@ -282,6 +280,11 @@ LLAgentCamera::~LLAgentCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
{
+ if (gDisconnected)
+ {
+ return;
+ }
+
if (gAgent.getAutoPilot())
{
gAgent.stopAutoPilot(TRUE);
@@ -348,8 +351,21 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
mCameraFOVZoomFactor = 0.f;
}
-
+ resetPanDiff();
+ resetOrbitDiff();
mHUDTargetZoom = 1.f;
+
+ if (LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ {
+ // resetting camera also resets position overrides in debug mode 'AllowSelectAvatar'
+ LLObjectSelectionHandle selected_handle = LLSelectMgr::getInstance()->getSelection();
+ if (selected_handle->getObjectCount() == 1
+ && selected_handle->getFirstObject() != NULL
+ && selected_handle->getFirstObject()->isAvatar())
+ {
+ LLSelectMgr::getInstance()->resetObjectOverrides(selected_handle);
+ }
+ }
}
// Allow camera to be moved somewhere other than behind avatar.
@@ -718,7 +734,7 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
return TRUE;
}
-F32 LLAgentCamera::getCameraZoomFraction()
+F32 LLAgentCamera::getCameraZoomFraction(bool get_third_person)
{
// 0.f -> camera zoomed all the way out
// 1.f -> camera zoomed all the way in
@@ -728,7 +744,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
// already [0,1]
return mHUDTargetZoom;
}
- else if (mFocusOnAvatar && cameraThirdPerson())
+ else if (get_third_person || (mFocusOnAvatar && cameraThirdPerson()))
{
return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
}
@@ -790,13 +806,16 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
if (mFocusObject.notNull())
{
- if (mFocusObject->isAvatar())
- {
- min_zoom = AVATAR_MIN_ZOOM;
- }
- else
+ if (mFocusObject.notNull())
{
- min_zoom = OBJECT_MIN_ZOOM;
+ if (mFocusObject->isAvatar())
+ {
+ min_zoom = AVATAR_MIN_ZOOM;
+ }
+ else
+ {
+ min_zoom = OBJECT_MIN_ZOOM;
+ }
}
}
@@ -830,6 +849,7 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians)
}
else
{
+ mOrbitAroundRadians += radians;
mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
cameraZoomIn(1.f);
@@ -861,12 +881,34 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle)
LLVector3d left_axis;
left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
+ mOrbitOverAngle += angle_from_up - new_angle;
mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
cameraZoomIn(1.f);
}
}
+void LLAgentCamera::resetCameraOrbit()
+{
+ LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
+ camera_offset_unit.normalize();
+
+ LLVector3d left_axis;
+ left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+ mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis);
+
+ mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f);
+
+ cameraZoomIn(1.f);
+ resetOrbitDiff();
+}
+
+void LLAgentCamera::resetOrbitDiff()
+{
+ mOrbitAroundRadians = 0;
+ mOrbitOverAngle = 0;
+}
+
//-----------------------------------------------------------------------------
// cameraZoomIn()
//-----------------------------------------------------------------------------
@@ -1005,6 +1047,8 @@ void LLAgentCamera::cameraPanIn(F32 meters)
LLVector3d at_axis;
at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
+ mPanFocusDiff += meters * at_axis;
+
mFocusTargetGlobal += meters * at_axis;
mFocusGlobal = mFocusTargetGlobal;
// don't enforce zoom constraints as this is the only way for users to get past them easily
@@ -1021,6 +1065,8 @@ void LLAgentCamera::cameraPanLeft(F32 meters)
LLVector3d left_axis;
left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+ mPanFocusDiff += meters * left_axis;
+
mFocusTargetGlobal += meters * left_axis;
mFocusGlobal = mFocusTargetGlobal;
@@ -1041,6 +1087,8 @@ void LLAgentCamera::cameraPanUp(F32 meters)
LLVector3d up_axis;
up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
+ mPanFocusDiff += meters * up_axis;
+
mFocusTargetGlobal += meters * up_axis;
mFocusGlobal = mFocusTargetGlobal;
@@ -1053,6 +1101,26 @@ void LLAgentCamera::cameraPanUp(F32 meters)
mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
}
+void LLAgentCamera::resetCameraPan()
+{
+ mFocusTargetGlobal -= mPanFocusDiff;
+
+ mFocusGlobal = mFocusTargetGlobal;
+ mCameraSmoothingStop = true;
+
+ cameraZoomIn(1.f);
+ updateFocusOffset();
+
+ mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+
+ resetPanDiff();
+}
+
+void LLAgentCamera::resetPanDiff()
+{
+ mPanFocusDiff.clear();
+}
+
//-----------------------------------------------------------------------------
// updateLookAt()
//-----------------------------------------------------------------------------
@@ -1604,7 +1672,7 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
agent_rot *= ((LLViewerObject*)(gAgentAvatarp->getParent()))->getRenderRotation();
}
- focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial[mCameraPreset]->get(), TYPE_VEC3D, "");
+ focus_offset = convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
return focus_offset * agent_rot;
}
@@ -1679,7 +1747,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
F32 camera_land_height;
LLVector3d frame_center_global = !isAgentAvatarValid() ?
gAgent.getPositionGlobal() :
- gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
+ gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
BOOL isConstrained = FALSE;
LLVector3d head_offset;
@@ -1753,7 +1821,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
at_axis.mV[VZ] = 0.f;
at_axis.normalize();
gAgent.resetAxes(at_axis * ~parent_rot);
-
+
local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot;
}
else
@@ -1934,9 +2002,38 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
+LLVector3 LLAgentCamera::getCurrentCameraOffset()
+{
+ return (LLViewerCamera::getInstance()->getOrigin() - getAvatarRootPosition() - mThirdPersonHeadOffset) * ~getCurrentAvatarRotation();
+}
+
+LLVector3d LLAgentCamera::getCurrentFocusOffset()
+{
+ return (mFocusTargetGlobal - gAgent.getPositionGlobal()) * ~getCurrentAvatarRotation();
+}
+
+LLQuaternion LLAgentCamera::getCurrentAvatarRotation()
+{
+ LLViewerObject* sit_object = (LLViewerObject*)gAgentAvatarp->getParent();
+
+ LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
+ LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
+ return av_rot * obj_rot;
+}
+
+bool LLAgentCamera::isJoystickCameraUsed()
+{
+ return ((mOrbitAroundRadians != 0) || (mOrbitOverAngle != 0) || !mPanFocusDiff.isNull());
+}
+
LLVector3 LLAgentCamera::getCameraOffsetInitial()
{
- return convert_from_llsd<LLVector3>(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, "");
+ return convert_from_llsd<LLVector3>(mCameraOffsetInitial->get(), TYPE_VEC3, "");
+}
+
+LLVector3d LLAgentCamera::getFocusOffsetInitial()
+{
+ return convert_from_llsd<LLVector3d>(mFocusOffsetInitial->get(), TYPE_VEC3D, "");
}
F32 LLAgentCamera::getCameraMaxZoomDistance()
@@ -1947,6 +2044,12 @@ F32 LLAgentCamera::getCameraMaxZoomDistance()
LLWorld::getInstance()->getRegionWidthInMeters() - CAMERA_FUDGE_FROM_OBJECT);
}
+LLVector3 LLAgentCamera::getAvatarRootPosition()
+{
+ static LLCachedControl<bool> use_hover_height(gSavedSettings, "HoverHeightAffectsCamera");
+ return use_hover_height ? gAgentAvatarp->mRoot->getWorldPosition() : gAgentAvatarp->mRoot->getWorldPosition() - gAgentAvatarp->getHoverOffset();
+
+}
//-----------------------------------------------------------------------------
// handleScrollWheel()
//-----------------------------------------------------------------------------
@@ -2226,15 +2329,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
}
// Remove any pitch from the avatar
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
- {
- LLQuaternion obj_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis * ~obj_rot);
- }
- else
+ if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
{
at_axis = gAgent.getFrameAgent().getAtAxis();
at_axis.mV[VZ] = 0.f;
@@ -2333,7 +2428,10 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
mCameraPreset = preset;
- gSavedSettings.setU32("CameraPreset", mCameraPreset);
+ resetPanDiff();
+ resetOrbitDiff();
+
+ gSavedSettings.setU32("CameraPresetType", mCameraPreset);
}
@@ -2578,7 +2676,7 @@ void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camer
//-----------------------------------------------------------------------------
// setFocusOnAvatar()
//-----------------------------------------------------------------------------
-void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
+void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL reset_axes)
{
if (focus_on_avatar != mFocusOnAvatar)
{
@@ -2595,27 +2693,28 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
//RN: when focused on the avatar, we're not "looking" at it
// looking implies intent while focusing on avatar means
// you're just walking around with a camera on you...eesh.
- if (!mFocusOnAvatar && focus_on_avatar)
+ if (!mFocusOnAvatar && focus_on_avatar && reset_axes)
{
setFocusGlobal(LLVector3d::zero);
mCameraFOVZoomFactor = 0.f;
if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
{
LLVector3 at_axis;
- if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
{
- LLQuaternion obj_rot = ((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis * ~obj_rot);
- }
- else
- {
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- gAgent.resetAxes(at_axis);
+ // In case of front view rotate agent to look into direction opposite to camera
+ // In case of rear view rotate agent into diraction same as camera, e t c
+ LLVector3 vect = getCameraOffsetInitial();
+ F32 rotxy = F32(atan2(vect.mV[VY], vect.mV[VX]));
+
+ LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+ // front view angle rotxy is zero, rear view rotxy angle is 180, compensate
+ frameCamera.yaw((180 * DEG_TO_RAD) - rotxy);
+ at_axis = frameCamera.getAtAxis();
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis);
+ gAgent.yaw(0);
}
}
}
@@ -2758,6 +2857,17 @@ BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object,
return mPointAt->setPointAt(target_type, object, position);
}
+void LLAgentCamera::rotateToInitSitRot()
+{
+ gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
+ gAgent.rotate(mInitSitRot);
+}
+
+void LLAgentCamera::resetCameraZoomFraction()
+{
+ mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
+}
+
ELookAtType LLAgentCamera::getLookAtType()
{
if (mLookAt)
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index a4bc8434b0..ec1ed433d7 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -56,7 +56,10 @@ enum ECameraPreset
CAMERA_PRESET_FRONT_VIEW,
/** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
- CAMERA_PRESET_GROUP_VIEW
+ CAMERA_PRESET_GROUP_VIEW,
+
+ /** Current view when a preset is saved */
+ CAMERA_PRESET_CUSTOM
};
//------------------------------------------------------------------------
@@ -109,20 +112,32 @@ private:
//--------------------------------------------------------------------
public:
void switchCameraPreset(ECameraPreset preset);
-private:
/** Determines default camera offset depending on the current camera preset */
LLVector3 getCameraOffsetInitial();
+ /** Determines default focus offset depending on the current camera preset */
+ LLVector3d getFocusOffsetInitial();
+
+ LLVector3 getCurrentCameraOffset();
+ LLVector3d getCurrentFocusOffset();
+ LLQuaternion getCurrentAvatarRotation();
+ bool isJoystickCameraUsed();
+ void setInitSitRot(LLQuaternion sit_rot) { mInitSitRot = sit_rot; };
+ void rotateToInitSitRot();
+
+private:
/** Determines maximum camera distance from target for mouselook, opposite to LAND_MIN_ZOOM */
F32 getCameraMaxZoomDistance();
/** Camera preset in Third Person Mode */
ECameraPreset mCameraPreset;
- /** Initial camera offsets */
- std::map<ECameraPreset, LLPointer<LLControlVariable> > mCameraOffsetInitial;
+ /** Initial camera offset */
+ LLPointer<LLControlVariable> mCameraOffsetInitial;
+
+ /** Initial focus offset */
+ LLPointer<LLControlVariable> mFocusOffsetInitial;
- /** Initial focus offsets */
- std::map<ECameraPreset, LLPointer<LLControlVariable> > mFocusOffsetInitial;
+ LLQuaternion mInitSitRot;
//--------------------------------------------------------------------
// Position
@@ -137,6 +152,8 @@ public:
F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); }
void clearCameraLag() { mCameraLag.clearVec(); }
private:
+ LLVector3 getAvatarRootPosition();
+
F32 mCurrentCameraDistance; // Current camera offset from avatar
F32 mTargetCameraDistance; // Target camera offset from avatar
F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object
@@ -204,7 +221,7 @@ public:
void validateFocusObject();
void setFocusGlobal(const LLPickInfo& pick);
void setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
- void setFocusOnAvatar(BOOL focus, BOOL animate);
+ void setFocusOnAvatar(BOOL focus, BOOL animate, BOOL reset_axes = TRUE);
void setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
void clearFocusObject();
void setFocusObject(LLViewerObject* object);
@@ -256,26 +273,31 @@ public:
void cameraOrbitAround(const F32 radians); // Rotate camera CCW radians about build focus point
void cameraOrbitOver(const F32 radians); // Rotate camera forward radians over build focus point
void cameraOrbitIn(const F32 meters); // Move camera in toward build focus point
-
+ void resetCameraOrbit();
+ void resetOrbitDiff();
//--------------------------------------------------------------------
// Zoom
//--------------------------------------------------------------------
public:
- void handleScrollWheel(S32 clicks); // Mousewheel driven zoom
- void cameraZoomIn(const F32 factor); // Zoom in by fraction of current distance
- F32 getCameraZoomFraction(); // Get camera zoom as fraction of minimum and maximum zoom
- void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
+ void handleScrollWheel(S32 clicks); // Mousewheel driven zoom
+ void cameraZoomIn(const F32 factor); // Zoom in by fraction of current distance
+ F32 getCameraZoomFraction(bool get_third_person = false); // Get camera zoom as fraction of minimum and maximum zoom
+ void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
F32 calcCameraFOVZoomFactor();
F32 getAgentHUDTargetZoom();
+ void resetCameraZoomFraction();
+ F32 getCurrentCameraZoomFraction() { return mCameraZoomFraction; }
+
//--------------------------------------------------------------------
// Pan
//--------------------------------------------------------------------
public:
void cameraPanIn(const F32 meters);
void cameraPanLeft(const F32 meters);
- void cameraPanUp(const F32 meters);
-
+ void cameraPanUp(const F32 meters);
+ void resetCameraPan();
+ void resetPanDiff();
//--------------------------------------------------------------------
// View
//--------------------------------------------------------------------
@@ -362,6 +384,9 @@ private:
F32 mOrbitInKey;
F32 mOrbitOutKey;
+ F32 mOrbitAroundRadians;
+ F32 mOrbitOverAngle;
+
//--------------------------------------------------------------------
// Pan
//--------------------------------------------------------------------
@@ -389,6 +414,8 @@ private:
F32 mPanInKey;
F32 mPanOutKey;
+ LLVector3d mPanFocusDiff;
+
/** Keys
** **
*******************************************************************************/
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 013c40f557..7f18ea6fe2 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -799,14 +799,13 @@ void LLAgentWearables::createStandardWearables()
((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
// no need to update here...
LLUUID category_id = LLUUID::null;
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
category_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
@@ -868,14 +867,13 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
const LLUUID& category_id,
BOOL notify)
{
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
category_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
@@ -883,13 +881,6 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index)
{
- if (gAgent.isTeen() &&
- (type == LLWearableType::WT_UNDERSHIRT || type == LLWearableType::WT_UNDERPANTS))
- {
- // Can't take off underclothing in simple UI mode or on PG accounts
- // TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx
- return;
- }
if (getWearableCount(type) == 0)
{
// no wearables to remove
@@ -1546,7 +1537,6 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
- LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
LLPointer<LLInventoryCallback> cb;
if(wear)
{
@@ -1569,13 +1559,13 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
folder_id = gInventory.findCategoryUUIDForType(folder_type);
}
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
folder_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
- asset_type, inv_type,
+ asset_type,
wearable->getType(),
LLFloaterPerms::getNextOwnerPerms("Wearables"),
cb);
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ee49125711..005259bcb8 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -44,6 +44,10 @@
const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
+std::list<AISAPI::ais_query_item_t> AISAPI::sPostponedQuery;
+
+const S32 MAX_SIMULTANEOUS_COROUTINES = 2048;
+
//-------------------------------------------------------------------------
/*static*/
bool AISAPI::isAvailable()
@@ -366,9 +370,51 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t
/*static*/
void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc)
{
+ LLCoprocedureManager &inst = LLCoprocedureManager::instance();
+ S32 pending_in_pool = inst.countPending("AIS");
std::string procFullName = "AIS(" + procName + ")";
- LLCoprocedureManager::instance().enqueueCoprocedure("AIS", procFullName, proc);
+ if (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES)
+ {
+ inst.enqueueCoprocedure("AIS", procFullName, proc);
+ }
+ else
+ {
+ // As I understand it, coroutines have built-in 'pending' pool
+ // but unfortunately it has limited size which inventory often goes over
+ // so this is a workaround to not overfill it.
+ if (sPostponedQuery.empty())
+ {
+ sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
+ gIdleCallbacks.addFunction(onIdle, NULL);
+ }
+ else
+ {
+ sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
+ }
+ }
+}
+/*static*/
+void AISAPI::onIdle(void *userdata)
+{
+ if (!sPostponedQuery.empty())
+ {
+ LLCoprocedureManager &inst = LLCoprocedureManager::instance();
+ S32 pending_in_pool = inst.countPending("AIS");
+ while (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES && !sPostponedQuery.empty())
+ {
+ ais_query_item_t &item = sPostponedQuery.front();
+ inst.enqueueCoprocedure("AIS", item.first, item.second);
+ sPostponedQuery.pop_front();
+ pending_in_pool++;
+ }
+ }
+
+ if (sPostponedQuery.empty())
+ {
+ // Nothing to do anymore
+ gIdleCallbacks.deleteFunction(onIdle, NULL);
+ }
}
/*static*/
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index e97059014b..856f3fc180 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -31,7 +31,6 @@
#include <map>
#include <set>
#include <string>
-#include "llhttpretrypolicy.h"
#include "llviewerinventory.h"
#include "llcorehttputil.h"
#include "llcoproceduremanager.h"
@@ -72,6 +71,7 @@ private:
const std::string, LLSD, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) > invokationFn_t;
static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc);
+ static void onIdle(void *userdata); // launches postponed AIS commands
static std::string getInvCap();
static std::string getLibCap();
@@ -80,6 +80,8 @@ private:
invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body,
completion_t callback, COMMAND_TYPE type);
+ typedef std::pair<std::string, LLCoprocedureManager::CoProcedure_t> ais_query_item_t;
+ static std::list<ais_query_item_t> sPostponedQuery;
};
class AISUpdate
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index afa4414968..134a34137b 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -522,20 +522,20 @@ void LLAppCoreHttp::refreshSettings(bool initial)
LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,
const LLCore::HttpHandler::ptr_t &handler, void *appdata)
{
- X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
- LLCore::HttpStatus result;
- LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
- LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
- LLSD validation_params = LLSD::emptyMap();
- LLURI uri(url);
+ LLCore::HttpStatus result;
+ try
+ {
+ X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
+ LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+ LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
+ LLSD validation_params = LLSD::emptyMap();
+ LLURI uri(url);
- validation_params[CERT_HOSTNAME] = uri.hostName();
+ validation_params[CERT_HOSTNAME] = uri.hostName();
- // *TODO: In the case of an exception while validating the cert, we need a way
- // to pass the offending(?) cert back out. *Rider*
+ // *TODO: In the case of an exception while validating the cert, we need a way
+ // to pass the offending(?) cert back out. *Rider*
- try
- {
// don't validate hostname. Let libcurl do it instead. That way, it'll handle redirects
store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
}
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 47fde299c7..3f1b5139c5 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -134,6 +134,7 @@
// called again. Since it returned false, do not yet cancel
// frameTimer.
handleQuit();
+ [[NSApplication sharedApplication] stopModal];
return NSTerminateCancel;
} else {
// pumpMainLoop() returned true: it's done. Okay, done with frameTimer.
@@ -294,6 +295,7 @@ struct AttachmentInfo
std::vector<AttachmentInfo> info{
AttachmentInfo(metadata.logFilePathname, "text/plain"),
AttachmentInfo(metadata.userSettingsPathname, "text/xml"),
+ AttachmentInfo(metadata.accountSettingsPathname, "text/xml"),
AttachmentInfo(metadata.staticDebugPathname, "text/xml")
};
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 3ac1c91cea..e8a3305645 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1029,14 +1029,13 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
- create_inventory_item(gAgent.getID(),
+ create_inventory_wearable(gAgent.getID(),
gAgent.getSessionID(),
lost_and_found_id,
wearable->getTransactionID(),
wearable->getName(),
wearable->getDescription(),
wearable->getAssetType(),
- LLInventoryType::IT_WEARABLE,
wearable->getType(),
wearable->getPermissions().getMaskNextOwner(),
cb);
@@ -1713,6 +1712,24 @@ void LLAppearanceMgr::slamCategoryLinks(const LLUUID& src_id, const LLUUID& dst_
LLInventoryModel::item_array_t* items;
LLSD contents = LLSD::emptyArray();
gInventory.getDirectDescendentsOf(src_id, cats, items);
+ if (!cats || !items)
+ {
+ // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
+ // that the cat just doesn't have any items or subfolders).
+ LLViewerInventoryCategory* category = gInventory.getCategory(src_id);
+ if (category)
+ {
+ LL_WARNS() << "Category '" << category->getName() << "' descendents corrupted, linking content failed." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Category could not be retrieved, linking content failed." << LL_ENDL;
+ }
+ llassert(cats != NULL && items != NULL);
+
+ return;
+ }
+
LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
iter != items->end();
@@ -1940,7 +1957,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Moved from LLWearableList::ContextMenu for wider utility.
-bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
+bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
{
// TODO: investigate wearables may not be loaded at this point EXT-8231
@@ -1950,7 +1967,7 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
// Count given clothes (by wearable type) and objects.
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
- LLViewerInventoryItem* item = gInventory.getItem(*it);
+ const LLViewerInventoryItem* item = gInventory.getItem(*it);
if (!item)
{
return false;
@@ -3261,6 +3278,50 @@ void update_base_outfit_after_ordering()
bool copy_folder_links = false;
app_mgr.slamCategoryLinks(app_mgr.getCOF(), base_outfit_id, copy_folder_links, dirty_state_updater);
+ if (base_outfit_id.notNull())
+ {
+ LLIsValidItemLink collector;
+
+ LLInventoryModel::cat_array_t cof_cats;
+ LLInventoryModel::item_array_t cof_item_array;
+ gInventory.collectDescendentsIf(app_mgr.getCOF(), cof_cats, cof_item_array,
+ LLInventoryModel::EXCLUDE_TRASH, collector);
+
+ for (U32 i = 0; i < outfit_item_array.size(); ++i)
+ {
+ LLViewerInventoryItem* linked_item = outfit_item_array.at(i)->getLinkedItem();
+ if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+ {
+ outfit_item_array.erase(outfit_item_array.begin() + i);
+ break;
+ }
+ }
+
+ if (outfit_item_array.size() != cof_item_array.size())
+ {
+ return;
+ }
+
+ std::sort(cof_item_array.begin(), cof_item_array.end(), sort_by_linked_uuid);
+ std::sort(outfit_item_array.begin(), outfit_item_array.end(), sort_by_linked_uuid);
+
+ for (U32 i = 0; i < cof_item_array.size(); ++i)
+ {
+ LLViewerInventoryItem *cof_it = cof_item_array.at(i);
+ LLViewerInventoryItem *base_it = outfit_item_array.at(i);
+
+ if (cof_it->getActualDescription() != base_it->getActualDescription())
+ {
+ if (cof_it->getLinkedUUID() == base_it->getLinkedUUID())
+ {
+ base_it->setDescription(cof_it->getActualDescription());
+ gInventory.updateItem(base_it);
+ }
+ }
+ }
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ }
+
}
// Save COF changes - update the contents of the current base outfit
@@ -3565,6 +3626,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
}
llcoro::suspend();
+ if (LLApp::isQuitting())
+ {
+ return;
+ }
S32 retryCount(0);
bool bRetry;
do
@@ -3628,6 +3693,11 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
+ if (LLApp::isQuitting())
+ {
+ return;
+ }
+
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -3663,6 +3733,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;
llcoro::suspendUntilTimeout(timeout);
+ if (LLApp::isQuitting())
+ {
+ return;
+ }
bRetry = true;
continue;
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index c274a8b049..8a55a848db 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -101,7 +101,7 @@ public:
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
// Can we add all referenced items to the avatar?
- bool canAddWearables(const uuid_vec_t& item_ids);
+ bool canAddWearables(const uuid_vec_t& item_ids) const;
// Copy all items in a category.
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a33e978c0a..c0971ba943 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -33,6 +33,7 @@
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
+#include "llenvironment.h"
#include "llerrorcontrol.h"
#include "lleventtimer.h"
#include "llviewertexturelist.h"
@@ -48,6 +49,7 @@
#include "llwindow.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
+#include "llkeyconflict.h" // for legacy keybinding support, remove later
#include "llmarketplacefunctions.h"
#include "llmarketplacenotifications.h"
#include "llmd5.h"
@@ -57,18 +59,23 @@
#include "llslurl.h"
#include "llstartup.h"
#include "llfocusmgr.h"
+#include "llurlfloaterdispatchhandler.h"
#include "llviewerjoystick.h"
#include "llallocator.h"
#include "llcalc.h"
#include "llconversationlog.h"
+#if LL_WINDOWS
#include "lldxhardware.h"
+#endif
#include "lltexturestats.h"
#include "lltrace.h"
#include "lltracethreadrecorder.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
+#include "llviewershadermgr.h"
#include "llviewermediafocus.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
@@ -84,6 +91,7 @@
#include "llsdutil_math.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
+#include "lltelemetry.h"
#include "llvector4a.h"
#include "llviewermenufile.h"
#include "llvoicechannel.h"
@@ -125,7 +133,7 @@
#include "llcoros.h"
#include "llexception.h"
#if !LL_LINUX
-#include "cef/dullahan.h"
+#include "cef/dullahan_version.h"
#include "vlc/libvlc_version.h"
#endif // LL_LINUX
@@ -145,7 +153,7 @@
#include "llapr.h"
#include <boost/lexical_cast.hpp>
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
#include "lllfsthread.h"
#include "llworkerthread.h"
#include "lltexturecache.h"
@@ -171,8 +179,6 @@
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
#include "llpostprocess.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -208,6 +214,7 @@
#include "llfloateroutfitsnapshot.h"
#include "llfloatersnapshot.h"
#include "llsidepanelinventory.h"
+#include "llatmosphere.h"
// includes for idle() idleShutdown()
#include "llviewercontrol.h"
@@ -251,9 +258,9 @@
// define a self-registering event API object
#include "llappviewerlistener.h"
-#if (LL_LINUX || LL_SOLARIS) && LL_GTK
+#if LL_LINUX && LL_GTK
#include "glib.h"
-#endif // (LL_LINUX || LL_SOLARIS) && LL_GTK
+#endif // (LL_LINUX) && LL_GTK
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -282,7 +289,7 @@ extern BOOL gHiDPISupport;
////////////////////////////////////////////////////////////
// All from the last globals push...
-F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
+F32 gSimLastTime; // Used in LLAppViewer::init and send_viewer_stats()
F32 gSimFrames;
BOOL gShowObjectUpdates = FALSE;
@@ -523,7 +530,8 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
LLIconCtrl* icon;
- if(gAgent.isInGroup(match_id, TRUE))
+ if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor
+ || gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group
{
LLGroupIconCtrl::Params icon_params;
icon_params.group_id = match_id;
@@ -601,8 +609,9 @@ static void settings_to_globals()
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
@@ -670,8 +679,10 @@ LLAppViewer::LLAppViewer()
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
- mPurgeOnExit(false),
+ mPurgeCacheOnExit(false),
+ mPurgeUserDataOnExit(false),
mSecondInstance(false),
+ mUpdaterNotFound(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
mQuitRequested(false),
@@ -775,6 +786,10 @@ bool LLAppViewer::init()
// Memory will be cleaned up in ::cleanupClass()
LLWearableType::initParamSingleton(new LLUITranslationBridge());
+ // initialize the LLSettingsType translation bridge.
+ LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();
+ LLSettingsType::initParamSingleton(trans);
+
// initialize SSE options
LLVector4a::initClass();
@@ -904,6 +919,7 @@ bool LLAppViewer::init()
// Load translations for tooltips
LLFloater::initClass();
+ LLUrlFloaterDispatchHandler::registerInDispatcher();
/////////////////////////////////////////////////
@@ -994,35 +1010,32 @@ bool LLAppViewer::init()
gGLManager.getGLInfo(gDebugInfo);
gGLManager.printGLInfoString();
- // Load Default bindings
- std::string key_bindings_file = gDirUtilp->findFile("keys.xml",
- gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
- gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-
-
- if (!gViewerKeyboard.loadBindingsXML(key_bindings_file))
- {
- std::string key_bindings_file = gDirUtilp->findFile("keys.ini",
- gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
- gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
- if (!gViewerKeyboard.loadBindings(key_bindings_file))
- {
- LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
- }
- }
-
// If we don't have the right GL requirements, exit.
if (!gGLManager.mHasRequirements)
{
// can't use an alert here since we're exiting and
// all hell breaks lose.
+ LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements");
OSMessageBox(
- LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
+ details.getString(),
LLStringUtil::null,
OSMB_OK);
return 0;
}
+ // If we don't have the right shader requirements.
+ if (!gGLManager.mHasShaderObjects
+ || !gGLManager.mHasVertexShader
+ || !gGLManager.mHasFragmentShader)
+ {
+ LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements");
+ OSMessageBox(
+ details.getString(),
+ LLStringUtil::null,
+ OSMB_OK);
+ return 0;
+ }
+
// Without SSE2 support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE2())
{
@@ -1088,6 +1101,46 @@ bool LLAppViewer::init()
}
}
+#if LL_WINDOWS && ADDRESS_SIZE == 64
+ if (gGLManager.mIsIntel)
+ {
+ // Check intel driver's version
+ // Ex: "3.1.0 - Build 8.15.10.2559";
+ std::string version = ll_safe_string((const char *)glGetString(GL_VERSION));
+
+ const boost::regex is_intel_string("[0-9].[0-9].[0-9] - Build [0-9]{1,2}.[0-9]{2}.[0-9]{2}.[0-9]{4}");
+
+ if (boost::regex_search(version, is_intel_string))
+ {
+ // Valid string, extract driver version
+ std::size_t found = version.find("Build ");
+ std::string driver = version.substr(found + 6);
+ S32 v1, v2, v3, v4;
+ S32 count = sscanf(driver.c_str(), "%d.%d.%d.%d", &v1, &v2, &v3, &v4);
+ if (count > 0 && v1 <= 10)
+ {
+ LL_INFOS("AppInit") << "Detected obsolete intel driver: " << driver << LL_ENDL;
+ LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
+ std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ details.setArg("[VERSION]", driver);
+ details.setArg("[GPUNAME]", gpu_name);
+ S32 button = OSMessageBox(details.getString(),
+ LLStringUtil::null,
+ OSMB_YESNO);
+ if (OSBTN_YES == button && gViewerWindow)
+ {
+ std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
+ if (gViewerWindow->getWindow())
+ {
+ gViewerWindow->getWindow()->spawnWebBrowser(url, false);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ // Obsolete? mExpectedGLVersion is always zero
#if LL_WINDOWS
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
{
@@ -1118,91 +1171,127 @@ bool LLAppViewer::init()
// Save the current version to the prefs file
gSavedSettings.setString("LastRunVersion",
- LLVersionInfo::getChannelAndVersion());
+ LLVersionInfo::instance().getChannelAndVersion());
gSimLastTime = gRenderStartTime.getElapsedTimeF32();
gSimFrames = (F32)gFrameCount;
- LLViewerJoystick::getInstance()->init(false);
+ if (gSavedSettings.getBOOL("JoystickEnabled"))
+ {
+ LLViewerJoystick::getInstance()->init(false);
+ }
try {
initializeSecHandler();
}
- catch (LLProtectedDataException ex)
+ catch (LLProtectedDataException&)
{
LLNotificationsUtil::add("CorruptedProtectedDataStore");
}
gGLActive = FALSE;
+#if LL_RELEASE_FOR_DOWNLOAD
+ if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
+ {
LLProcess::Params updater;
updater.desc = "updater process";
// Because it's the updater, it MUST persist beyond the lifespan of the
// viewer itself.
updater.autokill = false;
+ std::string updater_file;
#if LL_WINDOWS
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
+ updater_file = "SLVersionChecker.exe";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#elif LL_DARWIN
// explicitly run the system Python interpreter on SLVersionChecker.py
updater.executable = "python";
- updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
+ updater_file = "SLVersionChecker.py";
+ updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file));
#else
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
+ updater_file = "SLVersionChecker";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#endif
// add LEAP mode command-line argument to whichever of these we selected
updater.args.add("leap");
// UpdaterServiceSettings
- updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ {
+ // Befor first login, treat this as 'manual' updates,
+ // updater won't install anything, but required updates
+ updater.args.add("0");
+ }
+ else
+ {
+ updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+ }
// channel
- updater.args.add(LLVersionInfo::getChannel());
+ updater.args.add(LLVersionInfo::instance().getChannel());
// testok
updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
-#if LL_WINDOWS && !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS
- // This is neither a release package, nor crash-reporting enabled test build
- // try to run version updater, but don't bother if it fails (file might be missing)
- LLLeap *leap_p = LLLeap::create(updater, false);
- if (!leap_p)
- {
- LL_WARNS("LLLeap") << "Failed to run LLLeap" << LL_ENDL;
- }
-#else
- // Run the updater. An exception from launching the updater should bother us.
- LLLeap::create(updater, true);
-#endif
-
- // Iterate over --leap command-line options. But this is a bit tricky: if
- // there's only one, it won't be an array at all.
- LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
- LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
- if (LeapCommand.isDefined() && ! LeapCommand.isArray())
- {
- // If LeapCommand is actually a scalar value, make an array of it.
- // Have to do it in two steps because LeapCommand.append(LeapCommand)
- // trashes content! :-P
- LLSD item(LeapCommand);
- LeapCommand.append(item);
+ try
+ {
+ // Run the updater. An exception from launching the updater should bother us.
+ LLLeap::create(updater, true);
+ mUpdaterNotFound = false;
+ }
+ catch (...)
+ {
+ LLUIString details = LLNotifications::instance().getGlobalString("LLLeapUpdaterFailure");
+ details.setArg("[UPDATER_APP]", updater_file);
+ OSMessageBox(
+ details.getString(),
+ LLStringUtil::null,
+ OSMB_OK);
+ mUpdaterNotFound = true;
+ }
}
- BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
+ else
{
- LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
- // We don't have any better description of this plugin than the
- // user-specified command line. Passing "" causes LLLeap to derive a
- // description from the command line itself.
- // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
- // don't consider any one --leap command mission-critical, so if one
- // fails, log it, shrug and carry on.
- LLLeap::create("", leap, false); // exception=false
+ LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
}
+ if (mUpdaterNotFound)
+ {
+ LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL;
+ }
+ else
+ {
+ // Iterate over --leap command-line options. But this is a bit tricky: if
+ // there's only one, it won't be an array at all.
+ LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
+ LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
+ if (LeapCommand.isDefined() && !LeapCommand.isArray())
+ {
+ // If LeapCommand is actually a scalar value, make an array of it.
+ // Have to do it in two steps because LeapCommand.append(LeapCommand)
+ // trashes content! :-P
+ LLSD item(LeapCommand);
+ LeapCommand.append(item);
+ }
+ BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
+ {
+ LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
+ // We don't have any better description of this plugin than the
+ // user-specified command line. Passing "" causes LLLeap to derive a
+ // description from the command line itself.
+ // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
+ // don't consider any one --leap command mission-critical, so if one
+ // fails, log it, shrug and carry on.
+ LLLeap::create("", leap, false); // exception=false
+ }
+ }
+
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
<< "lleventhost no longer supported as a dynamic library"
<< LL_ENDL;
}
+#endif //LL_RELEASE_FOR_DOWNLOAD
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
@@ -1253,6 +1342,9 @@ bool LLAppViewer::init()
gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
+ // Load User's bindings
+ loadKeyBindings();
+
return true;
}
@@ -1273,39 +1365,8 @@ void LLAppViewer::initMaxHeapSize()
//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ;
F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ;
- BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemoryFailurePreventionEnabled") ;
-
- LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ;
-}
-
-void LLAppViewer::checkMemory()
-{
- const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second
- //const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds
- //static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ;
-
- if(!gGLManager.mDebugGPU)
- {
- return ;
- }
- if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32())
- {
- return ;
- }
- mMemCheckTimer.reset() ;
-
- //update the availability of memory
- LLMemory::updateMemoryInfo() ;
-
- bool is_low = LLMemory::isMemoryPoolLow() ;
-
- LLPipeline::throttleNewMemoryAllocation(is_low) ;
-
- if(is_low)
- {
- LLMemory::logMemoryInfo() ;
- }
+ LLMemory::initMaxHeapSizeGB(max_heap_size_gb);
}
static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
@@ -1314,6 +1375,8 @@ static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
+static LLTrace::BlockTimerStatHandle FTM_FETCH("Image Fetch");
+
static LLTrace::BlockTimerStatHandle FTM_VFS("VFS Thread");
static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
@@ -1341,7 +1404,7 @@ bool LLAppViewer::frame()
{
LOG_UNHANDLED_EXCEPTION("");
}
- catch (std::bad_alloc)
+ catch (std::bad_alloc&)
{
LLMemory::logMemoryInfo(TRUE);
LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
@@ -1382,9 +1445,6 @@ bool LLAppViewer::doFrame()
//clear call stack records
LL_CLEAR_CALLSTACKS();
- //check memory availability information
- checkMemory() ;
-
{
pingMainloopTimeout("Main:MiscNativeWindowEvents");
@@ -1420,6 +1480,8 @@ bool LLAppViewer::doFrame()
// canonical per-frame event
mainloop.post(newFrame);
+ // give listeners a chance to run
+ llcoro::suspend();
if (!LLApp::isExiting())
{
@@ -1438,6 +1500,7 @@ bool LLAppViewer::doFrame()
{
joystick->scanJoystick();
gKeyboard->scanKeyboard();
+ gViewerInput.scanMouse();
}
// Update state based on messages, user input, object idle.
@@ -1465,10 +1528,12 @@ bool LLAppViewer::doFrame()
pingMainloopTimeout("Main:Display");
gGLActive = TRUE;
+ display();
+
static U64 last_call = 0;
if (!gTeleportDisplay)
{
- // Frame/draw throttling
+ // Frame/draw throttling, controlled by FramePerSecondLimit
U64 elapsed_time = LLTimer::getTotalTime() - last_call;
if (elapsed_time < mMinMicroSecPerFrame)
{
@@ -1480,8 +1545,6 @@ bool LLAppViewer::doFrame()
}
last_call = LLTimer::getTotalTime();
- display();
-
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
@@ -1506,8 +1569,10 @@ bool LLAppViewer::doFrame()
}
// yield cooperatively when not running as foreground window
- if ( (gViewerWindow && !gViewerWindow->getWindow()->getVisible())
- || !gFocusMgr.getAppHasFocus())
+ // and when not quiting (causes trouble at mac's cleanup stage)
+ if (!LLApp::isExiting()
+ && ((gViewerWindow && !gViewerWindow->getWindow()->getVisible())
+ || !gFocusMgr.getAppHasFocus()))
{
// Sleep if we're not rendering, or the window is minimized.
static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40);
@@ -1607,12 +1672,15 @@ bool LLAppViewer::doFrame()
}
delete gServicePump;
+ gServicePump = NULL;
destroyMainloopTimeout();
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
+ LLPROFILE_UPDATE();
+
return ! LLApp::isRunning();
}
@@ -1628,7 +1696,7 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
}
{
- LL_RECORD_BLOCK_TIME(FTM_DECODE);
+ LL_RECORD_BLOCK_TIME(FTM_FETCH);
work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
}
return work_pending;
@@ -1651,6 +1719,8 @@ void LLAppViewer::flushVFSIO()
bool LLAppViewer::cleanup()
{
+ LLAtmosphere::cleanupClass();
+
//ditch LLVOAvatarSelf instance
gAgentAvatarp = NULL;
@@ -1662,7 +1732,11 @@ bool LLAppViewer::cleanup()
//dump scene loading monitor results
if (LLSceneMonitor::instanceExists())
{
- LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+ if (!isSecondInstance())
+ {
+ LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+ }
+ LLSceneMonitor::deleteSingleton();
}
// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
@@ -1679,24 +1753,9 @@ bool LLAppViewer::cleanup()
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
}
- {
- // Kill off LLLeap objects. We can find them all because LLLeap is derived
- // from LLInstanceTracker. But collect instances first: LLInstanceTracker
- // specifically forbids adding/deleting instances while iterating.
- std::vector<LLLeap*> leaps;
- leaps.reserve(LLLeap::instanceCount());
- for (LLLeap::instance_iter li(LLLeap::beginInstances()), lend(LLLeap::endInstances());
- li != lend; ++li)
- {
- leaps.push_back(&*li);
- }
- // Okay, now trash them all. We don't have to NULL or erase the entry
- // in 'leaps' because the whole vector is going away momentarily.
- BOOST_FOREACH(LLLeap* leap, leaps)
- {
- delete leap;
- }
- } // destroy 'leaps'
+ // Kill off LLLeap objects. We can find them all because LLLeap is derived
+ // from LLInstanceTracker.
+ LLLeap::instance_snapshot().deleteAll();
//flag all elements as needing to be destroyed immediately
// to ensure shutdown order
@@ -1708,6 +1767,11 @@ bool LLAppViewer::cleanup()
disconnectViewer();
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
+
+ if (gKeyboard)
+ {
+ gKeyboard->resetKeys();
+ }
display_cleanup();
@@ -1845,8 +1909,11 @@ bool LLAppViewer::cleanup()
delete gKeyboard;
gKeyboard = NULL;
- // Turn off Space Navigator and similar devices
- LLViewerJoystick::getInstance()->terminate();
+ if (LLViewerJoystick::instanceExists())
+ {
+ // Turn off Space Navigator and similar devices
+ LLViewerJoystick::getInstance()->terminate();
+ }
LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
@@ -1854,8 +1921,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLAvatarAppearance);
-
SUBSYSTEM_CLEANUP(LLPostProcess);
LLTracker::cleanupInstance();
@@ -1900,6 +1965,12 @@ bool LLAppViewer::cleanup()
// Store the time of our current logoff
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
+ if (LLEnvironment::instanceExists())
+ {
+ //Store environment settings if nessesary
+ LLEnvironment::getInstance()->saveToSettings();
+ }
+
// Must do this after all panels have been deleted because panels that have persistent rects
// save their rects on delete.
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
@@ -1923,6 +1994,11 @@ bool LLAppViewer::cleanup()
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
LL_INFOS() << "Saved settings" << LL_ENDL;
+
+ if (LLViewerParcelAskPlay::instanceExists())
+ {
+ LLViewerParcelAskPlay::getInstance()->saveSettings();
+ }
}
std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
@@ -1943,7 +2019,7 @@ bool LLAppViewer::cleanup()
LLConversationLog::instance().cache();
}
- if (mPurgeOnExit)
+ if (mPurgeCacheOnExit)
{
LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
@@ -1984,6 +2060,14 @@ bool LLAppViewer::cleanup()
}
}
+ if (mPurgeUserDataOnExit)
+ {
+ // Ideally we should not save anything from this session since it is going to be purged now,
+ // but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code
+ std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId();
+ gDirUtilp->deleteDirAndContents(user_path);
+ }
+
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
mAppCoreHttp.requestStop();
@@ -2038,6 +2122,7 @@ bool LLAppViewer::cleanup()
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
+ SUBSYSTEM_CLEANUP(LLImage);
SUBSYSTEM_CLEANUP(LLVFSThread);
SUBSYSTEM_CLEANUP(LLLFSThread);
@@ -2081,6 +2166,7 @@ bool LLAppViewer::cleanup()
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
LL_INFOS() << "File launched." << LL_ENDL;
}
+ // make sure nothing uses applyProxySettings by this point.
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
@@ -2091,29 +2177,19 @@ bool LLAppViewer::cleanup()
LLError::LLCallStacks::cleanup();
- removeMarkerFiles();
-
- // It's not at first obvious where, in this long sequence, generic cleanup
- // calls OUGHT to go. So let's say this: as we migrate cleanup from
+ // It's not at first obvious where, in this long sequence, a generic cleanup
+ // call OUGHT to go. So let's say this: as we migrate cleanup from
// explicit hand-placed calls into the generic mechanism, eventually
- // all cleanup will get subsumed into the generic calls. So the calls you
+ // all cleanup will get subsumed into the generic call. So the calls you
// still see above are calls that MUST happen before the generic cleanup
// kicks in.
- // This calls every remaining LLSingleton's cleanupSingleton() method.
- // This method should perform any cleanup that might take significant
- // realtime, or might throw an exception.
- LLSingletonBase::cleanupAll();
-
- // The logging subsystem depends on an LLSingleton. Any logging after
- // LLSingletonBase::deleteAll() won't be recorded.
- LL_INFOS() << "Goodbye!" << LL_ENDL;
-
- // This calls every remaining LLSingleton's deleteSingleton() method.
- // No class destructor should perform any cleanup that might take
- // significant realtime, or throw an exception.
+ // This calls every remaining LLSingleton's cleanupSingleton() and
+ // deleteSingleton() methods.
LLSingletonBase::deleteAll();
+ LL_INFOS() << "Goodbye!" << LL_ENDL;
+
removeDumpDir();
// return 0;
@@ -2146,7 +2222,7 @@ bool LLAppViewer::initThreads()
{
static const bool enable_threads = true;
- LLImage::initParamSingleton(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
@@ -2191,7 +2267,9 @@ void errorCallback(const std::string &error_string)
// static info file.
LLAppViewer::instance()->writeDebugInfo();
+#ifndef SHADER_CRASH_NONFATAL
LLError::crashAndLoop(error_string);
+#endif
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2622,7 +2700,7 @@ bool LLAppViewer::initConfiguration()
std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
if(! CmdLineChannel.empty())
{
- LLVersionInfo::resetChannel(CmdLineChannel);
+ LLVersionInfo::instance().resetChannel(CmdLineChannel);
}
// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
@@ -2843,12 +2921,11 @@ bool LLAppViewer::initConfiguration()
// Let anyone else who cares know that we've populated our settings
// variables.
- for (LLControlGroup::key_iter ki(LLControlGroup::beginKeys()), kend(LLControlGroup::endKeys());
- ki != kend; ++ki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
// For each named instance of LLControlGroup, send an event saying
// we've initialized an LLControlGroup instance by that name.
- LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", *ki));
+ LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key));
}
return true; // Config was successful.
@@ -3068,16 +3145,12 @@ LLSD LLAppViewer::getViewerInfo() const
// is available to a getInfo() caller as to the user opening
// LLFloaterAbout.
LLSD info;
- LLSD version;
- version.append(LLVersionInfo::getMajor());
- version.append(LLVersionInfo::getMinor());
- version.append(LLVersionInfo::getPatch());
- version.append(LLVersionInfo::getBuild());
- info["VIEWER_VERSION"] = version;
- info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
- info["CHANNEL"] = LLVersionInfo::getChannel();
+ auto& versionInfo(LLVersionInfo::instance());
+ info["VIEWER_VERSION"] = LLSDArray(versionInfo.getMajor())(versionInfo.getMinor())(versionInfo.getPatch())(versionInfo.getBuild());
+ info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
+ info["CHANNEL"] = versionInfo.getChannel();
info["ADDRESS_SIZE"] = ADDRESS_SIZE;
- std::string build_config = LLVersionInfo::getBuildConfig();
+ std::string build_config = versionInfo.getBuildConfig();
if (build_config != "Release")
{
info["BUILD_CONFIG"] = build_config;
@@ -3085,11 +3158,14 @@ LLSD LLAppViewer::getViewerInfo() const
// return a URL to the release notes for this viewer, such as:
// https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
- std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
- if (! LLStringUtil::endsWith(url, "/"))
- url += "/";
- url += LLURI::escape(LLVersionInfo::getVersion()) + ".html";
-
+ std::string url = versionInfo.getReleaseNotes(); // VVM supplied
+ if (url.empty())
+ {
+ url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+ if (!LLStringUtil::endsWith(url, "/"))
+ url += "/";
+ url += LLURI::escape(versionInfo.getVersion()) + ".html";
+ }
info["VIEWER_RELEASE_NOTES_URL"] = url;
// Position
@@ -3100,8 +3176,9 @@ LLSD LLAppViewer::getViewerInfo() const
info["POSITION"] = ll_sd_from_vector3d(pos);
info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
info["REGION"] = gAgent.getRegion()->getName();
- info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
- info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
+
+ boost::regex regex("\\.(secondlife|lindenlab)\\..*");
+ info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
info["SERVER_VERSION"] = gLastVersionChannel;
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
@@ -3113,8 +3190,8 @@ LLSD LLAppViewer::getViewerInfo() const
info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits<LLUnits::Megabytes>());
// Moved hack adjustment to Windows memory size into llsys.cpp
info["OS_VERSION"] = LLOSInfo::instance().getOSString();
- info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR));
- info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
+ info["GRAPHICS_CARD_VENDOR"] = ll_safe_string((const char*)(glGetString(GL_VENDOR)));
+ info["GRAPHICS_CARD"] = ll_safe_string((const char*)(glGetString(GL_RENDERER)));
#if LL_WINDOWS
std::string drvinfo = gDXHardware.getDriverVersionWMI();
@@ -3133,7 +3210,7 @@ LLSD LLAppViewer::getViewerInfo() const
}
#endif
- info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
+ info["OPENGL_VERSION"] = ll_safe_string((const char*)(glGetString(GL_VERSION)));
// Settings
@@ -3181,12 +3258,16 @@ LLSD LLAppViewer::getViewerInfo() const
cef_ver_codec << ".";
cef_ver_codec << DULLAHAN_VERSION_MINOR;
cef_ver_codec << ".";
+ cef_ver_codec << DULLAHAN_VERSION_POINT;
+ cef_ver_codec << ".";
cef_ver_codec << DULLAHAN_VERSION_BUILD;
- cef_ver_codec << " / CEF: ";
+ cef_ver_codec << std::endl;
+ cef_ver_codec << " CEF: ";
cef_ver_codec << CEF_VERSION;
- cef_ver_codec << " / Chromium: ";
+ cef_ver_codec << std::endl;
+ cef_ver_codec << " Chromium: ";
cef_ver_codec << CHROME_VERSION_MAJOR;
cef_ver_codec << ".";
cef_ver_codec << CHROME_VERSION_MINOR;
@@ -3379,12 +3460,12 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
#endif
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
- gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::getAddressSize();
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
+ gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize();
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
@@ -3427,7 +3508,7 @@ void LLAppViewer::writeSystemInfo()
// Dump some debugging info
LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
- LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -3449,6 +3530,12 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
+ std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
+ for (auto res_iter : resolutions)
+ {
+ gDebugInfo["DisplayInfo"].append(res_iter);
+ }
+
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
@@ -3553,7 +3640,7 @@ void LLAppViewer::handleViewerCrash()
if(gAgent.getRegion())
{
- gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
const LLVector3& loc = gAgent.getPositionAgent();
@@ -3649,7 +3736,7 @@ void LLAppViewer::handleViewerCrash()
// static
void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
{
- std::string marker_version(LLVersionInfo::getChannelAndVersion());
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
if ( marker_version.length() > MAX_MARKER_LENGTH )
{
LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
@@ -3666,7 +3753,7 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
{
bool sameVersion = false;
- std::string my_version(LLVersionInfo::getChannelAndVersion());
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
char marker_version[MAX_MARKER_LENGTH];
S32 marker_version_length;
@@ -3945,7 +4032,9 @@ void LLAppViewer::requestQuit()
gFloaterView->closeAllChildren(true);
}
- send_stats();
+ // Send preferences once, when exiting
+ bool include_preferences = true;
+ send_viewer_stats(include_preferences);
gLogoutTimer.reset();
mQuitRequested = true;
@@ -3965,7 +4054,11 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q
void LLAppViewer::userQuit()
{
- if (gDisconnected || gViewerWindow->getProgressView()->getVisible())
+ LL_INFOS() << "User requested quit" << LL_ENDL;
+ if (gDisconnected
+ || !gViewerWindow
+ || !gViewerWindow->getProgressView()
+ || gViewerWindow->getProgressView()->getVisible())
{
requestQuit();
}
@@ -4363,6 +4456,134 @@ void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
LLDeferredTaskList::instance().addTask(cb);
}
+void LLAppViewer::loadKeyBindings()
+{
+ std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
+#if 1
+ // Legacy support
+ // Remove #if-#endif section half a year after DRTVWR-501 releases.
+ // Mouse actions are part of keybinding file since DRTVWR-501 instead of being stored in
+ // settings.xml. To support legacy viewers that were storing in settings.xml we need to
+ // transfer old variables to new format.
+ // Also part of backward compatibility is present in LLKeyConflictHandler to modify
+ // legacy variables on changes in new system (to make sure we won't enforce
+ // legacy values again if user dropped to defaults in new system)
+ if (LLVersionInfo::getInstance()->getChannelAndVersion() != gLastRunVersion
+ || !gDirUtilp->fileExists(key_bindings_file)) // if file is missing, assume that there were no changes by user yet
+ {
+ // copy mouse actions and voice key changes to new file
+ LL_INFOS("InitInfo") << "Converting legacy mouse bindings to new format" << LL_ENDL;
+ // Load settings from file
+ LLKeyConflictHandler third_person_view(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ LLKeyConflictHandler sitting_view(LLKeyConflictHandler::MODE_SITTING);
+
+ // Since we are only modifying keybindings if personal file doesn't exist yet,
+ // it should be safe to just overwrite the value
+ // If key is already in use somewhere by default, LLKeyConflictHandler should resolve it.
+ BOOL value = gSavedSettings.getBOOL("DoubleClickAutoPilot");
+ third_person_view.registerControl("walk_to",
+ 0,
+ value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+ KEY_NONE,
+ MASK_NONE,
+ value);
+
+ U32 index = value ? 1 : 0; // we can store multiple combinations per action, so if first is in use by doubleclick, go to second
+ value = gSavedSettings.getBOOL("ClickToWalk");
+ third_person_view.registerControl("walk_to",
+ index,
+ value ? EMouseClickType::CLICK_LEFT : EMouseClickType::CLICK_NONE,
+ KEY_NONE,
+ MASK_NONE,
+ value);
+
+ value = gSavedSettings.getBOOL("DoubleClickTeleport");
+ third_person_view.registerControl("teleport_to",
+ 0,
+ value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+ KEY_NONE,
+ MASK_NONE,
+ value);
+
+ // sitting also supports teleport
+ sitting_view.registerControl("teleport_to",
+ 0,
+ value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+ KEY_NONE,
+ MASK_NONE,
+ value);
+
+ std::string key_string = gSavedSettings.getString("PushToTalkButton");
+ EMouseClickType mouse = EMouseClickType::CLICK_NONE;
+ KEY key = KEY_NONE;
+ if (key_string == "MiddleMouse")
+ {
+ mouse = EMouseClickType::CLICK_MIDDLE;
+ }
+ else if (key_string == "MouseButton4")
+ {
+ mouse = EMouseClickType::CLICK_BUTTON4;
+ }
+ else if (key_string == "MouseButton5")
+ {
+ mouse = EMouseClickType::CLICK_BUTTON5;
+ }
+ else
+ {
+ LLKeyboard::keyFromString(key_string, &key);
+ }
+
+ value = gSavedSettings.getBOOL("PushToTalkToggle");
+ std::string control_name = value ? "toggle_voice" : "voice_follow_key";
+ third_person_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+ sitting_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+
+ if (third_person_view.hasUnsavedChanges())
+ {
+ // calls loadBindingsXML()
+ third_person_view.saveToSettings();
+ }
+
+ if (sitting_view.hasUnsavedChanges())
+ {
+ // calls loadBindingsXML()
+ sitting_view.saveToSettings();
+ }
+
+ // in case of voice we need to repeat this in other modes
+
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ // edit and first person modes; MODE_SAVED_SETTINGS not in use at the moment
+ if (i != LLKeyConflictHandler::MODE_THIRD_PERSON && i != LLKeyConflictHandler::MODE_SITTING)
+ {
+ LLKeyConflictHandler handler((LLKeyConflictHandler::ESourceMode)i);
+
+ handler.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+
+ if (handler.hasUnsavedChanges())
+ {
+ // calls loadBindingsXML()
+ handler.saveToSettings();
+ }
+ }
+ }
+ }
+ // since something might have gone wrong or there might have been nothing to save
+ // (and because otherwise following code will have to be encased in else{}),
+ // load everything one last time
+#endif
+ if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+ {
+ // Failed to load custom bindings, try default ones
+ key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
+ if (!gViewerInput.loadBindingsXML(key_bindings_file))
+ {
+ LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+ }
+ }
+}
+
void LLAppViewer::purgeCache()
{
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
@@ -4455,7 +4676,7 @@ void LLAppViewer::badNetworkHandler()
// Flush all of our caches on exit in the case of disconnect due to
// invalid packets.
- mPurgeOnExit = TRUE;
+ mPurgeCacheOnExit = TRUE;
std::ostringstream message;
message <<
@@ -4495,6 +4716,7 @@ void LLAppViewer::saveFinalSnapshot()
gViewerWindow->getWindowWidthRaw(),
gViewerWindow->getWindowHeightRaw(),
FALSE,
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
TRUE,
LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
@@ -4623,6 +4845,9 @@ void LLAppViewer::idle()
LLFrameTimer::updateFrameTime();
LLFrameTimer::updateFrameCount();
LLEventTimer::updateClass();
+ // LLApp::stepFrame() performs the above three calls plus mRunner.run().
+ // Not sure why we don't call stepFrame() here, except that LLRunner seems
+ // completely redundant with LLEventTimer.
LLNotificationsUI::LLToast::updateClass();
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
@@ -4736,7 +4961,8 @@ void LLAppViewer::idle()
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
- send_stats();
+ bool include_preferences = false;
+ send_viewer_stats(include_preferences);
viewer_stats_timer.reset();
}
@@ -4818,13 +5044,14 @@ void LLAppViewer::idle()
{
return;
}
+
+ gViewerWindow->updateUI();
+
if (gTeleportDisplay)
{
return;
}
- gViewerWindow->updateUI();
-
///////////////////////////////////////
// Agent and camera movement
//
@@ -4918,7 +5145,6 @@ void LLAppViewer::idle()
//
// Update weather effects
//
- gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets
// Update wind vector
LLVector3 wind_position_region;
@@ -5147,11 +5373,56 @@ void LLAppViewer::sendLogoutRequest()
}
}
+void LLAppViewer::updateNameLookupUrl()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region || !region->capabilitiesReceived())
+ {
+ return;
+ }
+
+ LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
+ bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
+ std::string name_lookup_url;
+ name_lookup_url.reserve(128); // avoid a memory allocation below
+ name_lookup_url = region->getCapability("GetDisplayNames");
+ bool have_capability = !name_lookup_url.empty();
+ if (have_capability)
+ {
+ // we have support for display names, use it
+ U32 url_size = name_lookup_url.size();
+ // capabilities require URLs with slashes before query params:
+ // https://<host>:<port>/cap/<uuid>/?ids=<blah>
+ // but the caps are granted like:
+ // https://<host>:<port>/cap/<uuid>
+ if (url_size > 0 && name_lookup_url[url_size - 1] != '/')
+ {
+ name_lookup_url += '/';
+ }
+ name_cache->setNameLookupURL(name_lookup_url);
+ }
+ else
+ {
+ // Display names not available on this region
+ name_cache->setNameLookupURL(std::string());
+ }
+
+ // Error recovery - did we change state?
+ if (had_capability != have_capability)
+ {
+ // name tags are persistant on screen, so make sure they refresh
+ LLVOAvatar::invalidateNameTags();
+ }
+}
+
void LLAppViewer::idleNameCache()
{
// Neither old nor new name cache can function before agent has a region
LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
+ if (!region)
+ {
+ return;
+ }
// deal with any queued name requests and replies.
gCacheName->processPending();
@@ -5159,47 +5430,12 @@ void LLAppViewer::idleNameCache()
// Can't run the new cache until we have the list of capabilities
// for the agent region, and can therefore decide whether to use
// display names or fall back to the old name system.
- if (!region->capabilitiesReceived()) return;
-
- // Agent may have moved to a different region, so need to update cap URL
- // for name lookups. Can't do this in the cap grant code, as caps are
- // granted to neighbor regions before the main agent gets there. Can't
- // do it in the move-into-region code because cap not guaranteed to be
- // granted yet, for example on teleport.
- LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
- bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
- std::string name_lookup_url;
- name_lookup_url.reserve(128); // avoid a memory allocation below
- name_lookup_url = region->getCapability("GetDisplayNames");
- bool have_capability = !name_lookup_url.empty();
- if (have_capability)
- {
- // we have support for display names, use it
- U32 url_size = name_lookup_url.size();
- // capabilities require URLs with slashes before query params:
- // https://<host>:<port>/cap/<uuid>/?ids=<blah>
- // but the caps are granted like:
- // https://<host>:<port>/cap/<uuid>
- if (url_size > 0 && name_lookup_url[url_size-1] != '/')
- {
- name_lookup_url += '/';
- }
- name_cache->setNameLookupURL(name_lookup_url);
- }
- else
- {
- // Display names not available on this region
- name_cache->setNameLookupURL( std::string() );
- }
-
- // Error recovery - did we change state?
- if (had_capability != have_capability)
- {
- // name tags are persistant on screen, so make sure they refresh
- LLVOAvatar::invalidateNameTags();
- }
+ if (!region->capabilitiesReceived())
+ {
+ return;
+ }
- name_cache->idle();
+ LLAvatarNameCache::getInstance()->idle();
}
//
@@ -5236,37 +5472,40 @@ void LLAppViewer::idleNetwork()
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
- while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
{
- if (gDoDisconnect)
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(frame_count, gServicePump))
{
- // We're disconnecting, don't process any more messages from the server
- // We're usually disconnecting due to either network corruption or a
- // server going down, so this is OK.
- break;
- }
+ if (gDoDisconnect)
+ {
+ // We're disconnecting, don't process any more messages from the server
+ // We're usually disconnecting due to either network corruption or a
+ // server going down, so this is OK.
+ break;
+ }
- total_decoded++;
- gPacketsIn++;
+ total_decoded++;
+ gPacketsIn++;
- if (total_decoded > MESSAGE_MAX_PER_FRAME)
- {
- break;
- }
+ if (total_decoded > MESSAGE_MAX_PER_FRAME)
+ {
+ break;
+ }
#ifdef TIME_THROTTLE_MESSAGES
- // Prevent slow packets from completely destroying the frame rate.
- // This usually happens due to clumps of avatars taking huge amount
- // of network processing time (which needs to be fixed, but this is
- // a good limit anyway).
- total_time = check_message_timer.getElapsedTimeF32();
- if (total_time >= CheckMessagesMaxTime)
- break;
+ // Prevent slow packets from completely destroying the frame rate.
+ // This usually happens due to clumps of avatars taking huge amount
+ // of network processing time (which needs to be fixed, but this is
+ // a good limit anyway).
+ total_time = check_message_timer.getElapsedTimeF32();
+ if (total_time >= CheckMessagesMaxTime)
+ break;
#endif
- }
+ }
- // Handle per-frame message system processing.
- gMessageSystem->processAcks(gSavedSettings.getF32("AckCollectTime"));
+ // Handle per-frame message system processing.
+ lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
+ }
#ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime)
@@ -5402,7 +5641,7 @@ bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
{
if (evt.asInteger() > 0)
{
- mMinMicroSecPerFrame = 1000000 / evt.asInteger();
+ mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
}
else
{
@@ -5524,12 +5763,12 @@ void LLAppViewer::handleLoginComplete()
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
@@ -5548,7 +5787,7 @@ void LLAppViewer::handleLoginComplete()
if(gAgent.getRegion())
{
- gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 788fe6a19b..5ceb540784 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -95,6 +95,7 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
+ bool isUpdaterMissing() { return mUpdaterNotFound; }
void writeDebugInfo(bool isStatic=true);
@@ -190,9 +191,12 @@ public:
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
+ void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; }
void purgeCache(); // Clear the local cache.
void purgeCacheImmediate(); //clear local cache immediately.
S32 updateTextureThreads(F32 max_time);
+
+ void loadKeyBindings();
// mute/unmute the system's master audio
virtual void setMasterSystemAudioMute(bool mute);
@@ -204,7 +208,9 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
-
+
+ void updateNameLookupUrl();
+
protected:
virtual bool initWindow(); // Initialize the viewer's window.
virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system
@@ -229,7 +235,6 @@ private:
bool initConfiguration(); // Initialize settings from the command line/config file.
void initStrings(); // Initialize LLTrans machinery
bool initCache(); // Initialize local client cache.
- void checkMemory() ;
// We have switched locations of both Mac and Windows cache, make sure
// files migrate and old cache is cleared out.
@@ -261,6 +266,7 @@ private:
static LLAppViewer* sInstance;
bool mSecondInstance; // Is this a second instance of the app?
+ bool mUpdaterNotFound; // True when attempt to start updater failed
std::string mMarkerFileName;
LLAPRFile mMarkerFile; // A file created to indicate the app is running.
@@ -281,7 +287,8 @@ private:
std::string mSerialNumber;
bool mPurgeCache;
- bool mPurgeOnExit;
+ bool mPurgeCacheOnExit;
+ bool mPurgeUserDataOnExit;
LLViewerJoystick* joystick;
bool mSavedFinalSnapshot;
@@ -306,8 +313,6 @@ private:
LLAllocator mAlloc;
- LLFrameTimer mMemCheckTimer;
-
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
@@ -391,8 +396,6 @@ extern LLVector3 gRelativeWindVec;
extern U32 gPacketsIn;
extern BOOL gPrintMessagesThisFrame;
-extern LLUUID gSunTextureID;
-extern LLUUID gMoonTextureID;
extern LLUUID gBlackSquareID;
extern BOOL gRandomizeFramerate;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 6f32aab851..dc487967fc 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -73,10 +73,6 @@ static void exceptionTerminateHandler()
int main( int argc, char **argv )
{
-#if LL_SOLARIS && defined(__sparc)
- asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
-#endif
-
gArgC = argc;
gArgV = argv;
@@ -336,8 +332,6 @@ void LLAppViewerLinux::initCrashReporting(bool reportFreeze)
cmd += gDirUtilp->getDirDelimiter();
#if LL_LINUX
cmd += "linux-crash-logger.bin";
-#elif LL_SOLARIS
- cmd += "solaris-crash-logger";
#else
# error Unknown platform
#endif
@@ -394,9 +388,6 @@ bool LLAppViewerLinux::beingDebugged()
{
static enum {unknown, no, yes} debugged = unknown;
-#if LL_SOLARIS
- return debugged == no; // BUG: fix this for Solaris
-#else
if (debugged == unknown)
{
pid_t ppid = getppid();
@@ -431,7 +422,6 @@ bool LLAppViewerLinux::beingDebugged()
}
return debugged == yes;
-#endif
}
void LLAppViewerLinux::initLoggingAndGetLastDuration()
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
index 94250f1fc2..2380a8ebf0 100644
--- a/indra/newview/llappviewerlistener.cpp
+++ b/indra/newview/llappviewerlistener.cpp
@@ -52,10 +52,12 @@ LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter):
void LLAppViewerListener::requestQuit(const LLSD& event)
{
+ LL_INFOS() << "Listener requested quit" << LL_ENDL;
mAppViewerGetter()->requestQuit();
}
void LLAppViewerListener::forceQuit(const LLSD& event)
{
+ LL_INFOS() << "Listener requested force quit" << LL_ENDL;
mAppViewerGetter()->forceQuit();
}
diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h
index 37e8a3917a..79c3efff91 100644
--- a/indra/newview/llappviewermacosx-for-objc.h
+++ b/indra/newview/llappviewermacosx-for-objc.h
@@ -41,6 +41,7 @@ struct CrashMetadata
{
std::string logFilePathname;
std::string userSettingsPathname;
+ std::string accountSettingsPathname;
std::string staticDebugPathname;
std::string OSInfo;
std::string agentFullname;
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 3111540a13..662164af2d 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -199,10 +199,11 @@ CrashMetadataSingleton::CrashMetadataSingleton()
else
{
LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
- logFilePathname = get_metadata(info, "SLLog");
- userSettingsPathname = get_metadata(info, "SettingsFilename");
- OSInfo = get_metadata(info, "OSInfo");
- agentFullname = get_metadata(info, "LoginName");
+ logFilePathname = get_metadata(info, "SLLog");
+ userSettingsPathname = get_metadata(info, "SettingsFilename");
+ accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename");
+ OSInfo = get_metadata(info, "OSInfo");
+ agentFullname = get_metadata(info, "LoginName");
// Translate underscores back to spaces
LLStringUtil::replaceChar(agentFullname, '_', ' ');
regionName = get_metadata(info, "CurrentRegion");
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d208e135bb..9b1c0d1f8b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -139,6 +139,9 @@ namespace
{
// user name, when we have it
sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
+
+ sBugSplatSender->sendAdditionalFile(
+ WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "settings_per_account.xml")));
}
// LL_ERRS message, when there is one
@@ -500,68 +503,76 @@ void LLAppViewerWin32::disableWinErrorReporting()
}
const S32 MAX_CONSOLE_LINES = 500;
+// Only defined in newer SDKs than we currently use
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
+#endif
-static bool create_console()
-{
- int h_con_handle;
- long l_std_handle;
-
- CONSOLE_SCREEN_BUFFER_INFO coninfo;
- FILE *fp;
-
- // allocate a console for this app
- const bool isConsoleAllocated = AllocConsole();
-
- // set the screen buffer to be big enough to let us scroll text
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
- coninfo.dwSize.Y = MAX_CONSOLE_LINES;
- SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+namespace {
- // redirect unbuffered STDOUT to the console
- l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stdout handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "w" );
- *stdout = *fp;
- setvbuf( stdout, NULL, _IONBF, 0 );
- }
+void set_stream(const char* desc, FILE* fp, DWORD handle_id, const char* name, const char* mode="w");
- // redirect unbuffered STDIN to the console
- l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stdin handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "r" );
- *stdin = *fp;
- setvbuf( stdin, NULL, _IONBF, 0 );
- }
+bool create_console()
+{
+ // allocate a console for this app
+ const bool isConsoleAllocated = AllocConsole();
- // redirect unbuffered STDERR to the console
- l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stderr handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "w" );
- *stderr = *fp;
- setvbuf( stderr, NULL, _IONBF, 0 );
- }
+ if (isConsoleAllocated)
+ {
+ // set the screen buffer to be big enough to let us scroll text
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+ coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+ SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+
+ // redirect unbuffered STDOUT to the console
+ set_stream("stdout", stdout, STD_OUTPUT_HANDLE, "CONOUT$");
+ // redirect unbuffered STDERR to the console
+ set_stream("stderr", stderr, STD_ERROR_HANDLE, "CONOUT$");
+ // redirect unbuffered STDIN to the console
+ // Don't bother: our console is solely for log output. We never read stdin.
+// set_stream("stdin", stdin, STD_INPUT_HANDLE, "CONIN$", "r");
+ }
return isConsoleAllocated;
}
+void set_stream(const char* desc, FILE* fp, DWORD handle_id, const char* name, const char* mode)
+{
+ // SL-13528: This code used to be based on
+ // http://dslweb.nwnexus.com/~ast/dload/guicon.htm
+ // (referenced in https://stackoverflow.com/a/191880).
+ // But one of the comments on that StackOverflow answer points out that
+ // assigning to *stdout or *stderr "probably doesn't even work with the
+ // Universal CRT that was introduced in 2015," suggesting freopen_s()
+ // instead. Code below is based on https://stackoverflow.com/a/55875595.
+ auto std_handle = GetStdHandle(handle_id);
+ if (std_handle == INVALID_HANDLE_VALUE)
+ {
+ LL_WARNS() << "create_console() failed to get " << desc << " handle" << LL_ENDL;
+ }
+ else
+ {
+ if (mode == std::string("w"))
+ {
+ // Enable color processing on Windows 10 console windows.
+ DWORD dwMode = 0;
+ GetConsoleMode(std_handle, &dwMode);
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(std_handle, dwMode);
+ }
+ // Redirect the passed fp to the console.
+ FILE* ignore;
+ if (freopen_s(&ignore, name, mode, fp) == 0)
+ {
+ // use unbuffered I/O
+ setvbuf( fp, NULL, _IONBF, 0 );
+ }
+ }
+}
+
+} // anonymous namespace
+
LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) :
mCmdLine(cmd_line),
mIsConsoleAllocated(false)
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index d3e66289d1..0fd6009074 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -248,6 +248,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
{
if (isAgentAvatarValid() &&
gAgentAvatarp->isWearingAttachment(*it) &&
+ !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF!
!LLAppearanceMgr::instance().isLinkedInCOF(*it))
{
LLUUID item_id = *it;
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index a4ef762e8b..90aeff3032 100644
--- a/indra/newview/llattachmentsmgr.h
+++ b/indra/newview/llattachmentsmgr.h
@@ -30,8 +30,6 @@
#include "llsingleton.h"
-class LLViewerInventoryItem;
-
//--------------------------------------------------------------------------------
// LLAttachmentsMgr
//
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index b37aba6c15..4b6c855bde 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -29,8 +29,10 @@
#include "llaudiosourcevo.h"
+#include "llagent.h"
#include "llagentcamera.h"
#include "llmutelist.h"
+#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
@@ -54,6 +56,79 @@ void LLAudioSourceVO::setGain(const F32 gain)
mGain = llclamp(gain, 0.f, 1.f);
}
+void LLAudioSourceVO::checkCutOffRadius()
+{
+ if (mSourceMuted // already muted by something, will be recalculated on update()
+ || !mObjectp)
+ {
+ return;
+ }
+
+ F32 cutoff = mObjectp->getSoundCutOffRadius();
+ if (cutoff < 0.1f)
+ {
+ // consider cutoff below 0.1m as off (to avoid near zero comparison)
+ return;
+ }
+
+ LLVector3d pos_global = getPosGlobal();
+ if (!isInCutOffRadius(pos_global, cutoff))
+ {
+ mSourceMuted = true;
+ }
+}
+
+LLVector3d LLAudioSourceVO::getPosGlobal() const
+{
+ if (mObjectp->isAttachment())
+ {
+ LLViewerObject* parent = mObjectp;
+ while (parent && !parent->isAvatar())
+ {
+ parent = (LLViewerObject*)parent->getParent();
+ }
+ if (parent)
+ {
+ return parent->getPositionGlobal();
+ }
+ }
+ else
+ {
+ return mObjectp->getPositionGlobal();
+ }
+ return LLVector3d();
+}
+
+bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
+{
+ static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
+
+ LLVector3d pos_ear;
+
+ switch (ear_mode())
+ {
+ case 0: // camera
+ pos_ear = gAgentCamera.getCameraPositionGlobal();
+ break;
+
+ case 1: // avatar
+ case 2:
+ // voice support 'mixed' in '2' case with agent's position and camera's rotations
+ // but it is not defined in settings and uses camera as default
+ pos_ear = gAgent.getPositionGlobal();
+ break;
+
+ default:
+ pos_ear = gAgentCamera.getCameraPositionGlobal();
+ break;
+ }
+ LLVector3d to_vec = pos_global - pos_ear;
+
+ F32 dist = (F32)to_vec.magVec();
+
+ return dist < cutoff;
+}
+
void LLAudioSourceVO::updateMute()
{
if (!mObjectp || mObjectp->isDead())
@@ -63,26 +138,11 @@ void LLAudioSourceVO::updateMute()
}
bool mute = false;
- LLVector3d pos_global;
-
- if (mObjectp->isAttachment())
- {
- LLViewerObject* parent = mObjectp;
- while (parent && !parent->isAvatar())
- {
- parent = (LLViewerObject*)parent->getParent();
- }
- if (parent)
- {
- pos_global = parent->getPositionGlobal();
- }
- }
- else
- {
- pos_global = mObjectp->getPositionGlobal();
- }
+ LLVector3d pos_global = getPosGlobal();
- if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
+ 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;
}
diff --git a/indra/newview/llaudiosourcevo.h b/indra/newview/llaudiosourcevo.h
index f1d8ef4528..672a07f7d3 100644
--- a/indra/newview/llaudiosourcevo.h
+++ b/indra/newview/llaudiosourcevo.h
@@ -41,7 +41,11 @@ public:
/*virtual*/ void update();
/*virtual*/ void setGain(const F32 gain);
+ void checkCutOffRadius();
+
private:
+ LLVector3d getPosGlobal() const;
+ bool isInCutOffRadius(LLVector3d pos_global, const F32 cutoff) const;
void updateMute();
private:
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f0b74e7439..1797d2dd6e 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -626,10 +626,10 @@ namespace action_give_inventory
* Checks My Inventory visibility.
*/
- static bool is_give_inventory_acceptable()
+ static bool is_give_inventory_acceptable(LLInventoryPanel* panel = NULL)
{
// check selection in the panel
- const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
+ const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
if (inventory_selected_uuids.empty()) return false; // nothing selected
bool acceptable = false;
@@ -694,7 +694,7 @@ namespace action_give_inventory
uuid_vec_t mAvatarUuids;
};
- static void give_inventory_cb(const LLSD& notification, const LLSD& response)
+ static void give_inventory_cb(const LLSD& notification, const LLSD& response, std::set<LLUUID> inventory_selected_uuids)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
// if Cancel pressed
@@ -703,7 +703,6 @@ namespace action_give_inventory
return;
}
- const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
if (inventory_selected_uuids.empty())
{
return;
@@ -786,11 +785,11 @@ namespace action_give_inventory
* @param avatar_names - avatar names request to be sent.
* @param avatar_uuids - avatar names request to be sent.
*/
- static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names)
+ static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
{
llassert(avatar_names.size() == avatar_uuids.size());
- const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
+ const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
if (inventory_selected_uuids.empty())
{
return;
@@ -824,7 +823,7 @@ namespace action_give_inventory
substitutions["ITEMS"] = items;
LLShareInfo::instance().mAvatarNames = avatar_names;
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
- LLNotificationsUtil::add(notification, substitutions, LLSD(), &give_inventory_cb);
+ LLNotificationsUtil::add(notification, substitutions, LLSD(), boost::bind(&give_inventory_cb, _1, _2, inventory_selected_uuids));
}
}
@@ -877,11 +876,14 @@ void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::
}
//static
-std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
+std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs(LLInventoryPanel* active_panel)
{
std::set<LLFolderViewItem*> inventory_selected;
- LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
+ if (!active_panel)
+ {
+ active_panel = action_give_inventory::get_active_inventory_panel();
+ }
if (active_panel)
{
inventory_selected= active_panel->getRootFolder()->getSelectionList();
@@ -911,15 +913,16 @@ void LLAvatarActions::shareWithAvatars(LLView * panel)
{
using namespace action_give_inventory;
- LLFloater* root_floater = gFloaterView->getParentFloater(panel);
+ LLFloater* root_floater = gFloaterView->getParentFloater(panel);
+ LLInventoryPanel* inv_panel = dynamic_cast<LLInventoryPanel*>(panel);
LLFloaterAvatarPicker* picker =
- LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
+ LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, inv_panel), TRUE, FALSE, FALSE, root_floater->getName());
if (!picker)
{
return;
}
- picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
+ picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable, inv_panel));
picker->openFriendsTab();
if (root_floater)
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index b56d5b0fb9..7c721076c8 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -244,7 +244,7 @@ public:
*/
static void viewChatHistory(const LLUUID& id);
- static std::set<LLUUID> getInventorySelectedUUIDs();
+ static std::set<LLUUID> getInventorySelectedUUIDs(LLInventoryPanel* active_panel = NULL);
private:
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index a1dacd1a27..c510e86958 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -31,7 +31,6 @@
#include "lliconctrl.h"
#include "llavatarpropertiesprocessor.h"
-#include "llviewermenu.h"
class LLAvatarName;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 36d18114aa..b95cd68526 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -30,7 +30,6 @@
#include <boost/signals2.hpp>
#include "llpanel.h"
-#include "lloutputmonitorctrl.h"
#include "llbutton.h"
#include "lltextbox.h"
#include "llstyle.h"
@@ -38,6 +37,7 @@
#include "llcallingcard.h" // for LLFriendObserver
class LLAvatarIconCtrl;
+class LLOutputMonitorCtrl;
class LLAvatarName;
class LLIconCtrl;
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 856eb3414e..f41eb3daf4 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -253,6 +253,19 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_
return LLTrans::getString(payment_text);
}
+//static
+bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data)
+{
+ // Special accounts like M Linden don't have payment info revealed.
+ if (!avatar_data->caption_text.empty()) return true;
+
+ // Linden employees don't have payment info revealed
+ const S32 LINDEN_EMPLOYEE_INDEX = 3;
+ if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true;
+
+ return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index d5c5c75c69..b063048c26 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -232,6 +232,8 @@ public:
// Used for profiles, inspectors.
static std::string paymentInfo(const LLAvatarData* avatar_data);
+ static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 0b7b9cbbc7..9e7a8ba95c 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -48,11 +48,18 @@ LLChannelManager::LLChannelManager()
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
mChannelList.clear();
mStartUpChannel = NULL;
-
+
if(!gViewerWindow)
{
LL_ERRS() << "LLChannelManager::LLChannelManager() - viwer window is not initialized yet" << LL_ENDL;
}
+
+ // We don't actually need this instance right now, but our
+ // cleanupSingleton() method deletes LLScreenChannels, which need to
+ // unregister from LLUI. Calling LLUI::instance() here establishes the
+ // dependency so LLSingletonBase::deleteAll() calls our deleteSingleton()
+ // before LLUI::deleteSingleton().
+ LLUI::instance();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 54c6c985d6..e400609a74 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -57,8 +57,8 @@
#include "llinventorymodel.h"
#include "llmultigesture.h"
#include "llui.h"
-#include "llviewermenu.h"
#include "lluictrlfactory.h"
+#include "lluiusage.h"
//
// Globals
@@ -567,6 +567,8 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
// as soon as we say something, we no longer care about teaching the user
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
+
+ LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 1099d4bc09..c110e0d815 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -64,6 +64,7 @@
#include "llstring.h"
#include "llurlaction.h"
#include "llviewercontrol.h"
+#include "llviewermenu.h"
#include "llviewerobjectlist.h"
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
@@ -121,6 +122,7 @@ public:
mUserNameFont(NULL),
mUserNameTextBox(NULL),
mTimeBoxTextBox(NULL),
+ mNeedsTimeBox(true),
mAvatarNameCacheConnection()
{}
@@ -642,8 +644,19 @@ public:
user_name->setReadOnlyColor(style_params.readonly_color());
user_name->setColor(style_params.color());
- if (chat.mFromName.empty()
- || mSourceType == CHAT_SOURCE_SYSTEM)
+ if (mSourceType == CHAT_SOURCE_TELEPORT
+ && chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP)
+ {
+ mFrom = chat.mFromName;
+ mNeedsTimeBox = false;
+ user_name->setValue(mFrom);
+ updateMinUserNameWidth();
+ LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor");
+ setTransparentColor(sep_color);
+ mTimeBoxTextBox->setVisible(FALSE);
+ }
+ else if (chat.mFromName.empty()
+ || mSourceType == CHAT_SOURCE_SYSTEM)
{
mFrom = LLTrans::getString("SECOND_LIFE");
if(!chat.mFromName.empty() && (mFrom != chat.mFromName))
@@ -727,6 +740,9 @@ public:
case CHAT_SOURCE_SYSTEM:
icon->setValue(LLSD("SL_Logo"));
break;
+ case CHAT_SOURCE_TELEPORT:
+ icon->setValue(LLSD("Command_Destinations_Icon"));
+ break;
case CHAT_SOURCE_UNKNOWN:
icon->setValue(LLSD("Unknown_Icon"));
}
@@ -765,7 +781,7 @@ public:
S32 user_name_width = user_name_rect.getWidth();
S32 time_box_width = time_box->getRect().getWidth();
- if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
+ if (mNeedsTimeBox && !time_box->getVisible() && user_name_width > mMinUserNameWidth)
{
user_name_rect.mRight -= time_box_width;
user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@@ -967,6 +983,8 @@ protected:
LLTextBox* mUserNameTextBox;
LLTextBox* mTimeBoxTextBox;
+ bool mNeedsTimeBox;
+
private:
boost::signals2::connection mAvatarNameCacheConnection;
};
@@ -1085,7 +1103,8 @@ LLView* LLChatHistory::getSeparator()
LLView* LLChatHistory::getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args)
{
LLChatHistoryHeader* header = LLChatHistoryHeader::createInstance(mMessageHeaderFilename);
- header->setup(chat, style_params, args);
+ if (header)
+ header->setup(chat, style_params, args);
return header;
}
@@ -1200,6 +1219,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
+ bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT;
// We graying out chat history by graying out messages that contains full date in a time string
if (message_from_log)
{
@@ -1220,14 +1240,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
LLStyle::Params timestamp_style(body_message_params);
// out of the timestamp
- if (args["show_time"].asBoolean())
- {
- if (!message_from_log)
+ if (args["show_time"].asBoolean() && !teleport_separator)
{
- LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
- timestamp_style.color(timestamp_color);
- timestamp_style.readonly_color(timestamp_color);
- }
+ if (!message_from_log)
+ {
+ LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
+ timestamp_style.color(timestamp_color);
+ timestamp_style.readonly_color(timestamp_color);
+ }
mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
prependNewLineState = false;
}
@@ -1270,6 +1290,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
prependNewLineState, link_params);
prependNewLineState = false;
}
+ else if (teleport_separator)
+ {
+ std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat");
+ mEditor->appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>",
+ prependNewLineState, body_message_params);
+ prependNewLineState = false;
+ }
else
{
mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
@@ -1288,8 +1315,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
p.right_pad = mRightWidgetPad;
LLDate new_message_time = LLDate::now();
-
- if (mLastFromName == chat.mFromName
+ if (!teleport_separator
+ && mLastFromName == chat.mFromName
&& mLastFromID == chat.mFromID
&& mLastMessageTime.notNull()
&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
@@ -1298,6 +1325,12 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
view = getSeparator();
p.top_pad = mTopSeparatorPad;
p.bottom_pad = mBottomSeparatorPad;
+ if (!view)
+ {
+ // Might be wiser to make this LL_ERRS, getSeparator() should work in case of correct instalation.
+ LL_WARNS() << "Failed to create separator from " << mMessageSeparatorFilename << ": can't append to history" << LL_ENDL;
+ return;
+ }
}
else
{
@@ -1306,7 +1339,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
- p.bottom_pad = mBottomHeaderPad;
+ if (teleport_separator)
+ {
+ p.bottom_pad = mBottomSeparatorPad;
+ }
+ else
+ {
+ p.bottom_pad = mBottomHeaderPad;
+ }
+ if (!view)
+ {
+ LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL;
+ return;
+ }
}
p.view = view;
@@ -1344,10 +1389,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// We don't want multiple friendship offers to appear, this code checks if there are previous offers
// by iterating though all panels.
// Note: it might be better to simply add a "pending offer" flag somewhere
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ for (auto& panel : LLToastNotifyPanel::instance_snapshot())
{
- LLToastNotifyPanel& panel = *ti;
LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
const std::string& notification_name = panel.getNotificationName();
if (notification_name == "OfferFriendship"
@@ -1381,9 +1424,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
}
}
-
// usual messages showing
- else
+ else if(!teleport_separator)
{
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
@@ -1416,7 +1458,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
if (square_brackets)
{
message += "]";
- }
+ }
mEditor->appendText(message, prependNewLineState, body_message_params);
prependNewLineState = false;
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 4f42868f1a..1c22e055bb 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llchatitemscontainerctrl.h"
+#include "llchatmsgbox.h"
#include "lltextbox.h"
#include "llavataractions.h"
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index f66670ec8c..ebff9ca298 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -28,12 +28,13 @@
#define LL_LLCHATITEMSCONTAINERCTRL_H_
#include "llchat.h"
-#include "llchatmsgbox.h"
#include "llpanel.h"
#include "llscrollbar.h"
#include "llviewerchat.h"
#include "lltoastpanel.h"
+class LLChatMsgBox;
+
typedef enum e_show_item_header
{
CHATITEMHEADER_SHOW_ONLY_NAME = 0,
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index dedb06c945..0f187b0ecf 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -36,6 +36,7 @@
#include "llsingleton.h"
#include "llsyswellwindow.h"
#include "llfloaternotificationstabbed.h"
+#include "llviewermenu.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
@@ -1092,6 +1093,10 @@ void LLScriptChiclet::onMenuItemClicked(const LLSD& user_data)
{
LLScriptFloaterManager::instance().removeNotification(getSessionId());
}
+ else if ("close all" == action)
+ {
+ LLIMWellWindow::getInstance()->closeAll();
+ }
}
void LLScriptChiclet::createPopupMenu()
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 1caefd58ab..b31981b235 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -140,10 +140,31 @@ protected:
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Attachment.Touch", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
+ registrar.add("Attachment.Edit", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ enable_registrar.add("Attachment.OnEnable", boost::bind(&CofAttachmentContextMenu::onEnable, this, _2));
+
return createFromFile("menu_cof_attachment.xml");
}
+
+ bool onEnable(const LLSD& userdata)
+ {
+ const std::string event_name = userdata.asString();
+
+ if ("touch" == event_name)
+ {
+ return (1 == mUUIDs.size()) && (enable_attachment_touch(mUUIDs.front()));
+ }
+ else if ("edit" == event_name)
+ {
+ return (1 == mUUIDs.size()) && (get_is_item_editable(mUUIDs.front()));
+ }
+
+ return true;
+ }
};
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index 380fdccfa3..a17cab486a 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -36,7 +36,6 @@
// Classes
//
class LLColor4;
-class LLFloaterColorPicker;
class LLColorSwatchCtrl
: public LLUICtrl
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 76d965b1f1..23e2271eae 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -222,7 +222,7 @@ struct symbol_info
#define ent(SYMBOL) \
{ \
- #SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */ \
+ &#SYMBOL[28], /* skip "LLCommandHandler::UNTRUSTED_" prefix */ \
SYMBOL \
}
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index fe14bc081f..06d959ba3c 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -402,23 +402,30 @@ bool LLCommandLineParser::parseCommandLineString(const std::string& str)
}
}
- // Split the string content into tokens
- const char* escape_chars = "\\";
- const char* separator_chars = "\r\n ";
- const char* quote_chars = "\"'";
- boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
- boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
std::vector<std::string> tokens;
- // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
- for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
- i != tok.end();
- ++i)
+ try
{
- if(0 != i->size())
+ // Split the string content into tokens
+ const char* escape_chars = "\\";
+ const char* separator_chars = "\r\n ";
+ const char* quote_chars = "\"'";
+ boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
+ boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
+ // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
+ for (boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
+ i != tok.end();
+ ++i)
{
- tokens.push_back(*i);
+ if (0 != i->size())
+ {
+ tokens.push_back(*i);
+ }
}
}
+ catch (...)
+ {
+ CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("Unexpected crash while parsing: " << str));
+ }
po::command_line_parser clp(tokens);
return parseAndStoreResults(clp);
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 76e16f5a1f..3aaaaf52f5 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -347,6 +347,13 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren
bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
+ if (LLApp::isQuitting())
+ {
+ // Reply from coroutine came on shutdown
+ // We are quiting, don't start any more coroutines!
+ return true;
+ }
+
LLSD result;
LLCheckedHandle<LLFloaterCompileQueue> floater(hfloater);
// Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.
@@ -381,6 +388,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
LLSDMap("timeout", LLSD::Boolean(true)));
+ floater.check();
+
if (result.has("timeout"))
{ // A timeout filed in the result will always be true if present.
LLStringUtil::format_map_t args;
@@ -404,6 +413,12 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
}
+ if (!gAssetStorage)
+ {
+ // viewer likely is shutting down
+ return true;
+ }
+
{
HandleScriptUserData userData(pump.getName());
@@ -468,6 +483,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true)));
+ floater.check();
+
if (result.has("timeout"))
{ // A timeout filed in the result will always be true if present.
LLStringUtil::format_map_t args;
@@ -797,6 +814,7 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L
// but offers no guarantee of doing so.
llcoro::suspend();
}
+ floater.check();
}
floater->addStringMessage("Done");
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index 1b3d8f83a0..adb854875a 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -29,14 +29,11 @@
#include "llinventory.h"
#include "llviewerobject.h"
-#include "llvoinventorylistener.h"
#include "lluuid.h"
#include "llfloater.h"
#include "llscrolllistctrl.h"
-#include "llviewerinventory.h"
-
#include "llevents.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 92eeebd705..fab249f988 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -35,8 +35,6 @@
#include "llviewerregion.h"
#include "llskinningutil.h"
-//#pragma optimize("", off)
-
const F32 LLControlAvatar::MAX_LEGAL_OFFSET = 3.0f;
const F32 LLControlAvatar::MAX_LEGAL_SIZE = 64.0f;
@@ -80,6 +78,24 @@ void LLControlAvatar::initInstance()
mInitFlags |= 1<<4;
}
+const LLVOAvatar *LLControlAvatar::getAttachedAvatar() const
+{
+ if (mRootVolp && mRootVolp->isAttachment())
+ {
+ return mRootVolp->getAvatarAncestor();
+ }
+ return NULL;
+}
+
+LLVOAvatar *LLControlAvatar::getAttachedAvatar()
+{
+ if (mRootVolp && mRootVolp->isAttachment())
+ {
+ return mRootVolp->getAvatarAncestor();
+ }
+ return NULL;
+}
+
void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_scale_fixup) const
{
@@ -167,11 +183,14 @@ void LLControlAvatar::matchVolumeTransform()
if (mRootVolp->isAttachment())
{
- LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
+ LLVOAvatar *attached_av = getAttachedAvatar();
if (attached_av)
{
LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
- setPositionAgent(mRootVolp->getRenderPosition());
+ if (getRegion() && !isDead())
+ {
+ setPositionAgent(mRootVolp->getRenderPosition());
+ }
attach->updateWorldPRSParent();
LLVector3 joint_pos = attach->getWorldPosition();
LLQuaternion joint_rot = attach->getWorldRotation();
@@ -227,7 +246,10 @@ void LLControlAvatar::matchVolumeTransform()
#endif
setRotation(bind_rot*obj_rot);
mRoot->setWorldRotation(bind_rot*obj_rot);
- setPositionAgent(vol_pos);
+ if (getRegion() && !isDead())
+ {
+ setPositionAgent(vol_pos);
+ }
mRoot->setPosition(vol_pos + mPositionConstraintFixup);
F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale");
@@ -257,7 +279,7 @@ void LLControlAvatar::recursiveScaleJoint(LLJoint* joint, F32 factor)
{
joint->setScale(factor * joint->getScale());
- for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+ for (LLJoint::joints_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLJoint* child = *iter;
@@ -356,7 +378,34 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
}
}
-BOOL LLControlAvatar::updateCharacter(LLAgent &agent)
+bool LLControlAvatar::computeNeedsUpdate()
+{
+ computeUpdatePeriod();
+
+ // Animesh attachments are a special case. Should have the same update cadence as their attached parent avatar.
+ LLVOAvatar *attached_av = getAttachedAvatar();
+ if (attached_av)
+ {
+ // Have to run computeNeedsUpdate() for attached av in
+ // case it hasn't run updateCharacter() already this
+ // frame. Note this means that the attached av will
+ // run computeNeedsUpdate() multiple times per frame
+ // if it has animesh attachments. Results will be
+ // consistent except for the corner case of exceeding
+ // MAX_IMPOSTOR_INTERVAL in one call but not another,
+ // which should be rare.
+ attached_av->computeNeedsUpdate();
+ mNeedsImpostorUpdate = attached_av->mNeedsImpostorUpdate;
+ if (mNeedsImpostorUpdate)
+ {
+ mLastImpostorUpdateReason = 12;
+ }
+ return mNeedsImpostorUpdate;
+ }
+ return LLVOAvatar::computeNeedsUpdate();
+}
+
+bool LLControlAvatar::updateCharacter(LLAgent &agent)
{
return LLVOAvatar::updateCharacter(agent);
}
@@ -574,12 +623,12 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
return NULL;
}
- LLViewerObject* hit = NULL;
+ LLViewerObject* hit = NULL;
- if (lineSegmentBoundingBox(start, end))
- {
- LLVector4a local_end = end;
- LLVector4a local_intersection;
+ if (lineSegmentBoundingBox(start, end))
+ {
+ 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))
{
local_end = local_intersection;
@@ -598,20 +647,20 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
{
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))
- {
- local_end = local_intersection;
- if (intersection)
- {
- *intersection = local_intersection;
- }
+ {
+ local_end = local_intersection;
+ if (intersection)
+ {
+ *intersection = local_intersection;
+ }
hit = volp;
break;
}
}
}
- }
-
- return hit;
+ }
+
+ return hit;
}
// virtual
@@ -630,29 +679,23 @@ std::string LLControlAvatar::getFullname() const
// virtual
bool LLControlAvatar::shouldRenderRigged() const
{
- if (mRootVolp && mRootVolp->isAttachment())
- {
- LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
- if (attached_av)
- {
- return attached_av->shouldRenderRigged();
- }
- }
+ const LLVOAvatar *attached_av = getAttachedAvatar();
+ if (attached_av)
+ {
+ return attached_av->shouldRenderRigged();
+ }
return true;
}
// virtual
BOOL LLControlAvatar::isImpostor()
{
- if (mRootVolp && mRootVolp->isAttachment())
- {
- // Attached animated objects should match state of their attached av.
- LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
- if (attached_av)
- {
- return attached_av->isImpostor();
- }
- }
+ // Attached animated objects should match state of their attached av.
+ LLVOAvatar *attached_av = getAttachedAvatar();
+ if (attached_av)
+ {
+ return attached_av->isImpostor();
+ }
return LLVOAvatar::isImpostor();
}
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 288d07cd48..8e87299f3e 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -40,6 +40,10 @@ public:
virtual void initInstance(); // Called after construction to initialize the class.
virtual ~LLControlAvatar();
+ // If this is an attachment, return the avatar it is attached to. Otherwise NULL.
+ virtual const LLVOAvatar *getAttachedAvatar() const;
+ virtual LLVOAvatar *getAttachedAvatar();
+
void getNewConstraintFixups(LLVector3& new_pos_constraint, F32& new_scale_constraint) const;
void matchVolumeTransform();
void updateVolumeGeom();
@@ -53,7 +57,8 @@ public:
void markForDeath();
virtual void idleUpdate(LLAgent &agent, const F64 &time);
- virtual BOOL updateCharacter(LLAgent &agent);
+ virtual bool computeNeedsUpdate();
+ virtual bool updateCharacter(LLAgent &agent);
void getAnimatedVolumes(std::vector<LLVOVolume*>& volumes);
void updateAnimations();
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index f7c61efce0..a696c99a82 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -398,6 +398,24 @@ void LLConversationLog::deleteBackupLogs()
}
}
+void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name)
+{
+ conversations_vec_t::iterator conv_it = mConversations.begin();
+ for (; conv_it != mConversations.end(); ++conv_it)
+ {
+ if (conv_it->getSessionID() == session_id)
+ {
+ if (conv_it->getHistoryFileName() != expected_filename)
+ {
+ LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename);
+ conv_it->updateHistoryFileName(expected_filename);
+ conv_it->setConversationName(new_session_name);
+ }
+ break;
+ }
+ }
+}
+
bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
{
@@ -482,6 +500,10 @@ bool LLConversationLog::saveToFile(const std::string& filename)
conv_it->getSessionID().toString(conversation_id);
conv_it->getParticipantID().toString(participant_id);
+ bool is_adhoc = (conv_it->getConversationType() == LLIMModel::LLIMSession::ADHOC_SESSION);
+ std::string conv_name = is_adhoc ? conv_it->getConversationName() : LLURI::escape(conv_it->getConversationName());
+ std::string file_name = is_adhoc ? conv_it->getHistoryFileName() : LLURI::escape(conv_it->getHistoryFileName());
+
// examples of two file entries
// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
@@ -490,10 +512,10 @@ bool LLConversationLog::saveToFile(const std::string& filename)
(S32)conv_it->getConversationType(),
(S32)0,
(S32)conv_it->hasOfflineMessages(),
- conv_it->getConversationName().c_str(),
+ conv_name.c_str(),
participant_id.c_str(),
conversation_id.c_str(),
- LLURI::escape(conv_it->getHistoryFileName()).c_str());
+ file_name.c_str());
}
fclose(fp);
return true;
@@ -514,7 +536,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
}
bool purge_required = false;
- char buffer[MAX_STRING];
+ static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare
+
+ char buffer[UTF_BUFFER];
char conv_name_buffer[MAX_STRING];
char part_id_buffer[MAX_STRING];
char conv_id_buffer[MAX_STRING];
@@ -525,11 +549,14 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
// before CHUI-348 it was a flag of conversation voice state
int prereserved_unused;
- while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+ memset(buffer, '\0', UTF_BUFFER);
+ while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp))
{
- conv_name_buffer[0] = '\0';
- part_id_buffer[0] = '\0';
- conv_id_buffer[0] = '\0';
+ // force blank for added safety
+ memset(conv_name_buffer, '\0', MAX_STRING);
+ memset(part_id_buffer, '\0', MAX_STRING);
+ memset(conv_id_buffer, '\0', MAX_STRING);
+ memset(history_file_name, '\0', MAX_STRING);
sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
&time,
@@ -541,14 +568,18 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
conv_id_buffer,
history_file_name);
+ bool is_adhoc = ((SessionType)stype == LLIMModel::LLIMSession::ADHOC_SESSION);
+ std::string conv_name = is_adhoc ? conv_name_buffer : LLURI::unescape(conv_name_buffer);
+ std::string file_name = is_adhoc ? history_file_name : LLURI::unescape(history_file_name);
+
ConversationParams params;
params.time(LLUnits::Seconds::fromValue(time))
.conversation_type((SessionType)stype)
.has_offline_ims(has_offline_ims)
- .conversation_name(conv_name_buffer)
+ .conversation_name(conv_name)
.participant_id(LLUUID(part_id_buffer))
.session_id(LLUUID(conv_id_buffer))
- .history_filename(LLURI::unescape(history_file_name));
+ .history_filename(file_name);
LLConversation conversation(params);
@@ -562,6 +593,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
}
mConversations.push_back(conversation);
+ memset(buffer, '\0', UTF_BUFFER);
}
fclose(fp);
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 46e46a3278..820a5db491 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -59,7 +59,7 @@ public:
getTime() const { return mTime; }
bool hasOfflineMessages() const { return mHasOfflineIMs; }
- void setConversationName(std::string conv_name) { mConversationName = conv_name; }
+ void setConversationName(const std::string &conv_name) { mConversationName = conv_name; }
void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
bool isOlderThan(U32Days days) const;
@@ -68,6 +68,8 @@ public:
*/
void updateTimestamp();
+ void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; }
+
/*
* Resets flag of unread offline message to false when im floater with this conversation is opened.
*/
@@ -137,6 +139,8 @@ public:
* public method which is called on viewer exit to save conversation log
*/
void cache();
+ // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't
+ void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name);
bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
void deleteBackupLogs();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c258136889..a685639427 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -92,6 +92,23 @@ LLConversationItem::~LLConversationItem()
}
}
+//virtual
+void LLConversationItem::addChild(LLFolderViewModelItem* child)
+{
+ // Avoid duplicates: bail out if that child is already present in the list
+ // Note: this happens when models are created and 'parented' before views
+ // This is performance unfriendly, but conversation can addToFolder multiple times
+ child_list_t::const_iterator iter;
+ for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ if (child == *iter)
+ {
+ return;
+ }
+ }
+ LLFolderViewModelItemCommon::addChild(child);
+}
+
void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
{
LLUUID session_id = (session ? session->getUUID() : LLUUID());
@@ -324,11 +341,36 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
void LLConversationItemSession::clearParticipants()
{
+ // clearParticipants function potentially is malfunctioning since it only cleans children of models,
+ // it does nothing to views that own those models (listeners)
+ // probably needs to post some kind of 'remove all participants' event
clearChildren();
mIsLoaded = false;
mNeedsRefresh = true;
}
+
+void LLConversationItemSession::clearAndDeparentModels()
+{
+ std::for_each(mChildren.begin(), mChildren.end(),
+ [](LLFolderViewModelItem* c)
+ {
+ if (c->getNumRefs() == 0)
+ {
+ // LLConversationItemParticipant can be created but not assigned to any view,
+ // it was waiting for an "add_participant" event to be processed
+ delete c;
+ }
+ else
+ {
+ // Model is still assigned to some view/widget
+ c->setParent(NULL);
+ }
+ }
+ );
+ mChildren.clear();
+}
+
LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
{
// This is *not* a general tree parsing algorithm. It assumes that a session contains only
@@ -338,7 +380,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
{
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
- if (participant->hasSameValue(participant_id))
+ if (participant && participant->hasSameValue(participant_id))
{
break;
}
@@ -449,7 +491,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
{
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
F64 participant_time;
- if (participant->getTime(participant_time))
+ if (participant && participant->getTime(participant_time))
{
has_time = true;
most_recent_time = llmax(most_recent_time,participant_time);
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 80385fad5f..787deeb594 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -96,6 +96,7 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
virtual BOOL isUpToDate() const { return TRUE; }
virtual bool hasChildren() const { return FALSE; }
+ virtual void addChild(LLFolderViewModelItem* child);
virtual bool potentiallyVisible() { return true; }
virtual bool filter( LLFolderViewFilter& filter) { return false; }
@@ -164,6 +165,7 @@ public:
void removeParticipant(LLConversationItemParticipant* participant);
void removeParticipant(const LLUUID& participant_id);
void clearParticipants();
+ void clearAndDeparentModels(); // will delete unowned models and deparent owned ones
LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 0075b62100..65cec68884 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -31,6 +31,7 @@
#include <boost/bind.hpp>
#include "llagentdata.h"
+#include "llavataractions.h"
#include "llconversationmodel.h"
#include "llfloaterimsession.h"
#include "llfloaterimnearbychat.h"
@@ -102,6 +103,56 @@ LLConversationViewSession::~LLConversationViewSession()
mFlashTimer->unset();
}
+void LLConversationViewSession::destroyView()
+{
+ // Chat can create and parent models(listeners) to session's model before creating
+ // coresponding views, such participant's models normally will wait for idle cycles
+ // but since we are deleting session and won't be processing any more events, make
+ // sure unowned LLConversationItemParticipant models are removed as well.
+
+ LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+
+ // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent
+ // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant)
+ if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
+ {
+ // Destroy existing views
+ while (!mItems.empty())
+ {
+ LLFolderViewItem *itemp = mItems.back();
+ mItems.pop_back();
+
+ LLFolderViewModelItem* item_vmi = itemp->getViewModelItem();
+ if (item_vmi) // supposed to exist
+ {
+ // unparent to remove from child list
+ vmi->removeChild(item_vmi);
+ }
+ itemp->destroyView();
+ }
+
+ // Not needed in scope of sessions, but just in case
+ while (!mFolders.empty())
+ {
+ LLFolderViewFolder *folderp = mFolders.back();
+ mFolders.pop_back();
+
+ LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem();
+ if (folder_vmi)
+ {
+ vmi->removeChild(folder_vmi);
+ }
+ folderp->destroyView();
+ }
+
+ // Now everything that is left in model(listener) is not owned by views,
+ // only by sessions, deparent so it won't point to soon to be dead model
+ vmi->clearAndDeparentModels();
+ }
+
+ LLFolderViewFolder::destroyView();
+}
+
void LLConversationViewSession::setFlashState(bool flash_state)
{
if (flash_state && !mFlashStateOn)
@@ -175,7 +226,7 @@ BOOL LLConversationViewSession::postBuild()
LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
icon->setVisible(true);
icon->setValue(session->mOtherParticipantID);
- mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
+ mSpeakingIndicator->setSpeakerId(session->mOtherParticipantID, session->mSessionID, true);
mHasArrow = false;
}
break;
@@ -430,10 +481,15 @@ void LLConversationViewSession::refresh()
// Refresh the session view from its model data
LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
vmi->resetRefresh();
-
+
if (mSessionTitle)
- {
- mSessionTitle->setText(vmi->getDisplayName());
+ {
+ if (!highlightFriendTitle(vmi))
+ {
+ LLStyle::Params title_style;
+ title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+ mSessionTitle->setText(vmi->getDisplayName(), title_style);
+ }
}
// Update all speaking indicators
@@ -478,6 +534,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
}
}
+bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi)
+{
+ if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+ {
+ LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID());
+ if (session && LLAvatarActions::isFriend(session->mOtherParticipantID))
+ {
+ LLStyle::Params title_style;
+ title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+ mSessionTitle->setText(vmi->getDisplayName(), title_style);
+ return true;
+ }
+ }
+ return false;
+}
+
//
// Implementation of conversations list participant (avatar) widgets
//
@@ -545,7 +617,9 @@ BOOL LLConversationViewParticipant::postBuild()
}
updateChildren();
- return LLFolderViewItem::postBuild();
+ LLFolderViewItem::postBuild();
+ refresh();
+ return TRUE;
}
void LLConversationViewParticipant::draw()
@@ -576,7 +650,14 @@ void LLConversationViewParticipant::draw()
}
else
{
- color = mIsSelected ? sHighlightFgColor : sFgColor;
+ if (LLAvatarActions::isFriend(mUUID))
+ {
+ color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+ }
+ else
+ {
+ color = mIsSelected ? sHighlightFgColor : sFgColor;
+ }
}
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
@@ -615,11 +696,14 @@ void LLConversationViewParticipant::refresh()
{
// Refresh the participant view from its model data
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
- participant_model->resetRefresh();
-
- // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
- mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
-
+ if (participant_model)
+ {
+ participant_model->resetRefresh();
+
+ // *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();
}
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 420c250dfe..0932d24dfe 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -34,7 +34,9 @@
#include "lloutputmonitorctrl.h"
class LLTextBox;
+class LLFloater;
class LLFloaterIMContainer;
+class LLConversationItem;
class LLConversationViewSession;
class LLConversationViewParticipant;
@@ -65,6 +67,8 @@ protected:
public:
virtual ~LLConversationViewSession();
+ /*virtual*/ void destroyView();
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -92,6 +96,8 @@ public:
LLFloater* getSessionFloater();
bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; }
+ bool highlightFriendTitle(LLConversationItem* vmi);
+
private:
void onCurrentVoiceSessionChanged(const LLUUID& session_id);
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index b4a1457f47..232e461fd0 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -166,11 +166,11 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
gAgent.getSecureSessionID().asString());
keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
- keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
- keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
- keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
- keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
- keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::getBuild());
+ keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel());
+ keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
+ keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
+ keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
+ keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);
@@ -241,11 +241,11 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
{
keywordArgs.appendString("password", password);
}
- keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
- keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
- keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
- keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
- keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::getBuild());
+ keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel());
+ keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
+ keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
+ keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
+ keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);
@@ -454,7 +454,7 @@ void LLCurrencyUIManager::Impl::updateUI()
if (!mUserEnteredCurrencyBuy)
{
- if (!mZeroMessage.empty() && mUserCurrencyBuy == 0)
+ if (mUserCurrencyBuy == 0)
{
lindenAmount->setText(LLStringUtil::null);
}
@@ -467,8 +467,9 @@ void LLCurrencyUIManager::Impl::updateUI()
}
}
- mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", getLocalEstimate());
- mPanel.getChildView("currency_est")->setVisible( hasEstimate() && mUserCurrencyBuy > 0);
+ std::string estimated = (mUserCurrencyBuy == 0) ? mPanel.getString("estimated_zero") : getLocalEstimate();
+ mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", estimated);
+ mPanel.getChildView("currency_est")->setVisible( hasEstimate() || mUserCurrencyBuy == 0);
mPanel.getChildView("currency_links")->setVisible( mSupportsInternationalBilling);
mPanel.getChildView("exchange_rate_note")->setVisible( mSupportsInternationalBilling);
@@ -603,6 +604,11 @@ bool LLCurrencyUIManager::bought()
return impl.mBought;
}
+void LLCurrencyUIManager::clearError()
+{
+ impl.clearError();
+}
+
bool LLCurrencyUIManager::hasError()
{
return impl.mError;
diff --git a/indra/newview/llcurrencyuimanager.h b/indra/newview/llcurrencyuimanager.h
index 3f37db8db1..7c05acbb05 100644
--- a/indra/newview/llcurrencyuimanager.h
+++ b/indra/newview/llcurrencyuimanager.h
@@ -80,6 +80,8 @@ public:
bool buying(); // are we in the process of buying?
bool bought(); // did the buy() transaction complete successfully
+ void clearError();
+
bool hasError();
std::string errorMessage();
std::string errorURI();
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
deleted file mode 100644
index 803e2b2fb2..0000000000
--- a/indra/newview/lldaycyclemanager.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * @file lldaycyclemanager.cpp
- * @brief Implementation for the LLDayCycleManager class.
- *
- * $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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lldaycyclemanager.h"
-
-#include "lldiriterator.h"
-
-void LLDayCycleManager::getPresetNames(preset_name_list_t& names) const
-{
- names.clear();
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- names.push_back(it->first);
- }
-}
-
-void LLDayCycleManager::getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const
-{
- user.clear();
- sys.clear();
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- const std::string& name = it->first;
-
- if (isSystemPreset(name))
- {
- sys.push_back(name);
- }
- else
- {
- user.push_back(name);
- }
- }
-}
-
-void LLDayCycleManager::getUserPresetNames(preset_name_list_t& user) const
-{
- preset_name_list_t sys; // unused
- getPresetNames(user, sys);
-}
-
-bool LLDayCycleManager::getPreset(const std::string name, LLWLDayCycle& day_cycle) const
-{
- dc_map_t::const_iterator it = mDayCycleMap.find(name);
- if (it == mDayCycleMap.end())
- {
- return false;
- }
-
- day_cycle = it->second;
- return true;
-}
-
-bool LLDayCycleManager::getPreset(const std::string name, LLSD& day_cycle) const
-{
- LLWLDayCycle dc;
- if (!getPreset(name, dc))
- {
- return false;
- }
-
- day_cycle = dc.asLLSD();
- return true;
-}
-
-bool LLDayCycleManager::presetExists(const std::string name) const
-{
- LLWLDayCycle dummy;
- return getPreset(name, dummy);
-}
-
-bool LLDayCycleManager::isSystemPreset(const std::string& name) const
-{
- return gDirUtilp->fileExists(getSysDir() + LLURI::escape(name) + ".xml");
-}
-
-bool LLDayCycleManager::savePreset(const std::string& name, const LLSD& data)
-{
- // Save given preset.
- LLWLDayCycle day;
- day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
- day.save(getUserDir() + LLURI::escape(name) + ".xml");
-
- // Add it to our map.
- addPreset(name, data);
- mModifySignal();
- return true;
-}
-
-bool LLDayCycleManager::deletePreset(const std::string& name)
-{
- // Remove it from the map.
- dc_map_t::iterator it = mDayCycleMap.find(name);
- if (it == mDayCycleMap.end())
- {
- LL_WARNS("Windlight") << "No day cycle named " << name << LL_ENDL;
- return false;
- }
- mDayCycleMap.erase(it);
-
- // Remove from the filesystem.
- std::string filename = LLURI::escape(name) + ".xml";
- if (gDirUtilp->fileExists(getUserDir() + filename))
- {
- gDirUtilp->deleteFilesInDir(getUserDir(), filename);
- }
-
- // Signal interested parties.
- mModifySignal();
- return true;
-}
-
-bool LLDayCycleManager::isSkyPresetReferenced(const std::string& preset_name) const
-{
- // We're traversing local day cycles, they can only reference local skies.
- LLWLParamKey key(preset_name, LLEnvKey::SCOPE_LOCAL);
-
- for (dc_map_t::const_iterator it = mDayCycleMap.begin(); it != mDayCycleMap.end(); ++it)
- {
- if (it->second.hasReferencesTo(key))
- {
- return true;
- }
- }
-
- return false;
-}
-
-boost::signals2::connection LLDayCycleManager::setModifyCallback(const modify_signal_t::slot_type& cb)
-{
- return mModifySignal.connect(cb);
-}
-
-// virtual
-void LLDayCycleManager::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL;
- loadAllPresets();
-}
-
-void LLDayCycleManager::loadAllPresets()
-{
- mDayCycleMap.clear();
-
- // First, load system (coming out of the box) day cycles.
- loadPresets(getSysDir());
-
- // Then load user presets. Note that user day cycles will modify any system ones already loaded.
- loadPresets(getUserDir());
-}
-
-void LLDayCycleManager::loadPresets(const std::string& dir)
-{
- LLDirIterator dir_iter(dir, "*.xml");
-
- while (1)
- {
- std::string file;
- if (!dir_iter.next(file)) break; // no more files
- loadPreset(gDirUtilp->add(dir, file));
- }
-}
-
-bool LLDayCycleManager::loadPreset(const std::string& path)
-{
- LLSD data = LLWLDayCycle::loadDayCycleFromPath(path);
- if (data.isUndefined())
- {
- LL_WARNS() << "Error loading day cycle from " << path << LL_ENDL;
- return false;
- }
-
- std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
- addPreset(name, data);
-
- return true;
-}
-
-bool LLDayCycleManager::addPreset(const std::string& name, const LLSD& data)
-{
- if (name.empty())
- {
- //llassert(name.empty());
- return false;
- }
-
- LLWLDayCycle day;
- day.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
- mDayCycleMap[name] = day;
- return true;
-}
-
-// static
-std::string LLDayCycleManager::getSysDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "");
-}
-
-// static
-std::string LLDayCycleManager::getUserDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/days", "");
-}
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
deleted file mode 100644
index 04db9d5dac..0000000000
--- a/indra/newview/lldaycyclemanager.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file lldaycyclemanager.h
- * @brief Implementation for the LLDayCycleManager class.
- *
- * $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$
- */
-
-#ifndef LL_LLDAYCYCLEMANAGER_H
-#define LL_LLDAYCYCLEMANAGER_H
-
-#include <map>
-#include <string>
-
-#include "llwldaycycle.h"
-#include "llwlparammanager.h"
-
-/**
- * WindLight day cycles manager class
- *
- * Provides interface for accessing, loading and saving day cycles.
- */
-class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
-{
- LLSINGLETON_EMPTY_CTOR(LLDayCycleManager);
- LOG_CLASS(LLDayCycleManager);
-
-public:
- typedef std::list<std::string> preset_name_list_t;
-
- typedef std::map<std::string, LLWLDayCycle> dc_map_t;
- typedef boost::signals2::signal<void()> modify_signal_t;
-
- void getPresetNames(preset_name_list_t& names) const;
- void getPresetNames(preset_name_list_t& user, preset_name_list_t& sys) const;
- void getUserPresetNames(preset_name_list_t& user) const;
-
- bool getPreset(const std::string name, LLWLDayCycle& day_cycle) const;
- bool getPreset(const std::string name, LLSD& day_cycle) const;
- bool presetExists(const std::string name) const;
- bool isSystemPreset(const std::string& name) const;
- bool savePreset(const std::string& name, const LLSD& data);
- bool deletePreset(const std::string& name);
-
- /// @return true if there is a day cycle that refers to the sky preset.
- bool isSkyPresetReferenced(const std::string& preset_name) const;
-
- /// Emitted when a preset gets added or deleted.
- boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb);
-
-private:
- /*virtual*/ void initSingleton();
-
- void loadAllPresets();
- void loadPresets(const std::string& dir);
- bool loadPreset(const std::string& path);
- bool addPreset(const std::string& name, const LLSD& data);
-
- static std::string getSysDir();
- static std::string getUserDir();
-
- dc_map_t mDayCycleMap;
- modify_signal_t mModifySignal;
-};
-
-#endif // LL_LLDAYCYCLEMANAGER_H
diff --git a/indra/newview/lldensityctrl.cpp b/indra/newview/lldensityctrl.cpp
new file mode 100644
index 0000000000..298a309e7c
--- /dev/null
+++ b/indra/newview/lldensityctrl.cpp
@@ -0,0 +1,225 @@
+/**
+* @file lldensityctrl.cpp
+* @brief Control for specifying density over a height range for sky settings.
+*
+* $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$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldensityctrl.h"
+
+#include "llslider.h"
+#include "llsliderctrl.h"
+#include "llsettingssky.h"
+
+static LLDefaultChildRegistry::Register<LLDensityCtrl> register_density_control("densityctrl");
+
+const std::string LLDensityCtrl::DENSITY_RAYLEIGH("density_rayleigh");
+const std::string LLDensityCtrl::DENSITY_MIE("density_mie");
+const std::string LLDensityCtrl::DENSITY_ABSORPTION("density_absorption");
+
+namespace
+{
+ const std::string FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL("level_exponential");
+ const std::string FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE("exponential_scale");
+ const std::string FIELD_SKY_DENSITY_PROFILE_LINEAR("level_linear");
+ const std::string FIELD_SKY_DENSITY_PROFILE_CONSTANT("level_constant");
+ const std::string FIELD_SKY_DENSITY_MAX_ALTITUDE("max_altitude");
+ const std::string FIELD_SKY_DENSITY_ANISO_FACTOR("aniso_factor");
+ const std::string FIELD_SKY_DENSITY_ANISO_FACTOR_LABEL("aniso_factor_label");
+}
+
+const std::string& LLDensityCtrl::NameForDensityProfileType(DensityProfileType t)
+{
+ switch (t)
+ {
+ case Rayleigh: return DENSITY_RAYLEIGH;
+ case Mie: return DENSITY_MIE;
+ case Absorption: return DENSITY_ABSORPTION;
+ default:
+ break;
+ }
+
+ llassert(false);
+ return DENSITY_RAYLEIGH;
+}
+
+LLDensityCtrl::Params::Params()
+: image_density_feedback("image_density_feedback")
+, lbl_exponential("label_exponential")
+, lbl_exponential_scale("label_exponential_scale")
+, lbl_linear("label_linear")
+, lbl_constant("label_constant")
+, lbl_max_altitude("label_max_altitude")
+, lbl_aniso_factor("label_aniso_factor")
+, profile_type(LLDensityCtrl::Rayleigh)
+{
+}
+
+LLDensityCtrl::LLDensityCtrl(const Params& params)
+: mProfileType(params.profile_type)
+, mImgDensityFeedback(params.image_density_feedback)
+{
+
+}
+
+LLSD LLDensityCtrl::getProfileConfig()
+{
+ LLSD config;
+ switch (mProfileType)
+ {
+ case Rayleigh: return mSkySettings->getRayleighConfigs();
+ case Mie: return mSkySettings->getMieConfigs();
+ case Absorption: return mSkySettings->getAbsorptionConfigs();
+ default:
+ break;
+ }
+ llassert(false);
+ return config;
+}
+
+BOOL LLDensityCtrl::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onExponentialChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onExponentialScaleFactorChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLinearChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onConstantChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMaxAltitudeChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAnisoFactorChanged(); });
+
+ if (mProfileType != Mie)
+ {
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR_LABEL)->setValue(false);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR)->setVisible(false);
+ }
+
+ return TRUE;
+}
+
+void LLDensityCtrl::setEnabled(BOOL enabled)
+{
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setEnabled(enabled);
+
+ if (mProfileType == Mie)
+ {
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR)->setEnabled(enabled);
+ }
+}
+
+void LLDensityCtrl::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ LLSD config = getProfileConfig();
+
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM]);
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR]);
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_LINEAR)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM]);
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM]);
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MAX_ALTITUDE)->setValue(config[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH]);
+
+ if (mProfileType == Mie)
+ {
+ getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR)->setValue(config[LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR]);
+ }
+}
+
+void LLDensityCtrl::updateProfile()
+{
+ F32 exponential_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL)->getValueF32();
+ F32 exponential_scale = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_EXPONENTIAL_SCALE)->getValueF32();
+ F32 linear_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_LINEAR)->getValueF32();
+ F32 constant_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_PROFILE_CONSTANT)->getValueF32();
+ F32 max_alt = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MAX_ALTITUDE)->getValueF32();
+ F32 aniso_factor = 0.0f;
+
+ if (mProfileType == Mie)
+ {
+ aniso_factor = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ANISO_FACTOR)->getValueF32();
+ }
+
+ LLSD profile = LLSettingsSky::createSingleLayerDensityProfile(max_alt, exponential_term, exponential_scale, linear_term, constant_term, aniso_factor);
+
+ switch (mProfileType)
+ {
+ case Rayleigh: mSkySettings->setRayleighConfigs(profile); break;
+ case Mie: mSkySettings->setMieConfigs(profile); break;
+ case Absorption: mSkySettings->setAbsorptionConfigs(profile); break;
+ default:
+ break;
+ }
+}
+
+void LLDensityCtrl::onExponentialChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onExponentialScaleFactorChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onLinearChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onConstantChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onMaxAltitudeChanged()
+{
+ updateProfile();
+ updatePreview();
+}
+
+void LLDensityCtrl::onAnisoFactorChanged()
+{
+ updateProfile();
+}
+
+void LLDensityCtrl::updatePreview()
+{
+ // AdvancedAtmospherics TODO
+ // Generate image according to current density profile
+}
+
diff --git a/indra/newview/lldensityctrl.h b/indra/newview/lldensityctrl.h
new file mode 100644
index 0000000000..789022803c
--- /dev/null
+++ b/indra/newview/lldensityctrl.h
@@ -0,0 +1,104 @@
+/**
+* @file lldensityctrl.h
+* @brief Control for specifying density over a height range for sky settings.
+*
+* $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$
+*/
+
+#ifndef LLDENSITY_CTRL_H
+#define LLDENSITY_CTRL_H
+
+#include "lluictrl.h"
+#include "llsettingssky.h"
+#include "lltextbox.h"
+#include "llsliderctrl.h"
+
+class LLDensityCtrl : public LLUICtrl
+{
+public:
+ static const std::string DENSITY_RAYLEIGH;
+ static const std::string DENSITY_MIE;
+ static const std::string DENSITY_ABSORPTION;
+
+ // Type of density profile this tab is updating
+ enum DensityProfileType
+ {
+ Rayleigh,
+ Mie,
+ Absorption
+ };
+
+ static const std::string& NameForDensityProfileType(DensityProfileType t);
+
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Optional<LLTextBox::Params> lbl_exponential,
+ lbl_exponential_scale,
+ lbl_linear,
+ lbl_constant,
+ lbl_max_altitude,
+ lbl_aniso_factor;
+
+ Optional<LLSliderCtrl::Params> exponential_slider,
+ exponential_scale_slider,
+ linear_slider,
+ constant_slider,
+ aniso_factor_slider;
+
+ Optional<LLUIImage*> image_density_feedback;
+
+ DensityProfileType profile_type;
+ Params();
+ };
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+ void setProfileType(DensityProfileType t) { mProfileType = t; }
+
+ void refresh();
+ void updateProfile();
+
+ LLSettingsSky::ptr_t getSky() const { return mSkySettings; }
+ void setSky(const LLSettingsSky::ptr_t &sky) { mSkySettings = sky; refresh(); }
+
+protected:
+ friend class LLUICtrlFactory;
+ LLDensityCtrl(const Params&);
+
+ LLSD getProfileConfig();
+ void updatePreview();
+
+private:
+ void onExponentialChanged();
+ void onExponentialScaleFactorChanged();
+ void onLinearChanged();
+ void onConstantChanged();
+ void onMaxAltitudeChanged();
+ void onAnisoFactorChanged();
+
+ DensityProfileType mProfileType = Rayleigh;
+ LLUIImage* mImgDensityFeedback = nullptr;
+ LLSettingsSky::ptr_t mSkySettings;
+};
+
+#endif LLDENSITY_CTRL_H
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index b8e6e81ee6..01790ad19e 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -37,7 +37,7 @@
#include "llviewercontrol.h"
#include "llwin32headerslean.h"
-#if LL_LINUX || LL_SOLARIS || LL_DARWIN
+#if LL_LINUX || LL_DARWIN
# include "llfilepicker.h"
#endif
@@ -187,7 +187,7 @@ std::string LLDirPicker::getDirName()
return mFilePicker->getFirstFile();
}
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
LLDirPicker::LLDirPicker() :
mFileName(NULL),
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index c7dba12130..52febe4523 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -78,7 +78,7 @@ private:
void buildDirname( void );
bool check_local_file_access_enabled();
-#if LL_LINUX || LL_SOLARIS || LL_DARWIN
+#if LL_LINUX || LL_DARWIN
// On Linux we just implement LLDirPicker on top of LLFilePicker
LLFilePicker *mFilePicker;
#endif
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8c6cbc020b..507af56cb0 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -912,22 +912,18 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
if (volume->getAvatar())
{
const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents();
- LLVector3d cam_pos = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
- LLVector3 cam_region_pos = LLVector3(cam_pos - volume->getRegion()->getOriginGlobal());
-
- LLVector3 cam_to_box_offset = point_to_box_offset(cam_region_pos, av_box);
+ LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
+ LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname()
<< " pos (ignored) " << pos
- << " cam pos " << cam_pos
- << " cam region pos " << cam_region_pos
+ << " cam pos " << cam_pos_from_agent
<< " box " << av_box[0] << "," << av_box[1]
<< " -> dist " << mDistanceWRTCamera
<< LL_ENDL;
mVObjp->updateLOD();
return;
}
-
}
else
{
@@ -1178,11 +1174,33 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
}
else if (isRoot())
{
- if (mSpatialBridge && (mSpatialBridge->asPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) != mVObjp->isHUDAttachment())
+ if (mSpatialBridge)
{
- // remove obsolete bridge
- mSpatialBridge->markDead();
- setSpatialBridge(NULL);
+ U32 partition_type = mSpatialBridge->asPartition()->mPartitionType;
+ bool is_hud = mVObjp->isHUDAttachment();
+ bool is_animesh = mVObjp->isAnimatedObject() && mVObjp->getControlAvatar() != NULL;
+ bool is_attachment = mVObjp->isAttachment() && !is_hud && !is_animesh;
+ if ((partition_type == LLViewerRegion::PARTITION_HUD) != is_hud)
+ {
+ // Was/became HUD
+ // remove obsolete bridge
+ mSpatialBridge->markDead();
+ setSpatialBridge(NULL);
+ }
+ else if ((partition_type == LLViewerRegion::PARTITION_CONTROL_AV) != is_animesh)
+ {
+ // Was/became part of animesh
+ // remove obsolete bridge
+ mSpatialBridge->markDead();
+ setSpatialBridge(NULL);
+ }
+ else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment)
+ {
+ // Was/became part of avatar
+ // remove obsolete bridge
+ mSpatialBridge->markDead();
+ setSpatialBridge(NULL);
+ }
}
//must be an active volume
if (!mSpatialBridge)
@@ -1191,6 +1209,15 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
{
setSpatialBridge(new LLHUDBridge(this, getRegion()));
}
+ else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
+ {
+ setSpatialBridge(new LLControlAVBridge(this, getRegion()));
+ }
+ // check HUD first, because HUD is also attachment
+ else if (mVObjp->isAttachment())
+ {
+ setSpatialBridge(new LLAvatarBridge(this, getRegion()));
+ }
else
{
setSpatialBridge(new LLVolumeBridge(this, getRegion()));
@@ -1454,7 +1481,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
if (avatarp->isVisible())
{
- impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
+ impostor = objparent->isAvatar() && !LLPipeline::sImpostorRender && ((LLVOAvatar*) objparent)->isImpostor();
loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
}
else
@@ -1538,7 +1565,8 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
if (mDrawable->getVObj())
{
- if (mDrawable->getVObj()->isAttachment())
+ // Don't update if we are part of impostor, unles it's an impostor pass
+ if (!LLPipeline::sImpostorRender && mDrawable->getVObj()->isAttachment())
{
LLDrawable* parent = mDrawable->getParent();
if (parent && parent->getVObj())
@@ -1698,12 +1726,26 @@ void LLDrawable::updateFaceSize(S32 idx)
LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
: LLSpatialPartition(0, FALSE, 0, regionp)
{
- mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+ mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
mLODPeriod = 16;
mSlopRatio = 0.25f;
}
+LLAvatarPartition::LLAvatarPartition(LLViewerRegion* regionp)
+ : LLBridgePartition(regionp)
+{
+ mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+ mPartitionType = LLViewerRegion::PARTITION_AVATAR;
+}
+
+LLControlAVPartition::LLControlAVPartition(LLViewerRegion* regionp)
+ : LLBridgePartition(regionp)
+{
+ mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
+ mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
+}
+
LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
: LLVolumeBridge(drawablep, regionp)
{
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 82888b2df6..d583a692f9 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -86,7 +86,8 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
poolp = new LLDrawPoolAlpha();
break;
case POOL_AVATAR:
- poolp = new LLDrawPoolAvatar();
+ case POOL_CONTROL_AV:
+ poolp = new LLDrawPoolAvatar(type);
break;
case POOL_TREE:
poolp = new LLDrawPoolTree(tex0);
@@ -127,7 +128,7 @@ LLDrawPool::LLDrawPool(const U32 type)
mType = type;
sNumDrawPools++;
mId = sNumDrawPools;
- mVertexShaderLevel = 0;
+ mShaderLevel = 0;
mSkipRender = false;
}
@@ -141,7 +142,7 @@ LLViewerTexture *LLDrawPool::getDebugTexture()
return NULL;
}
-//virtuals
+//virtual
void LLDrawPool::beginRenderPass( S32 pass )
{
}
@@ -383,16 +384,6 @@ LLRenderPass::~LLRenderPass()
}
-LLDrawPool* LLRenderPass::instancePool()
-{
-#if LL_RELEASE_FOR_DOWNLOAD
- LL_WARNS() << "Attempting to instance a render pass. Invalid operation." << LL_ENDL;
-#else
- LL_ERRS() << "Attempting to instance a render pass. Invalid operation." << LL_ENDL;
-#endif
- return NULL;
-}
-
void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
@@ -406,9 +397,9 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
}
}
-void LLRenderPass::renderTexture(U32 type, U32 mask)
+void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
{
- pushBatches(type, mask, TRUE);
+ pushBatches(type, mask, true, batch_textures);
}
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
@@ -449,10 +440,10 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
if (params.mModelMatrix != gGLLastMatrix)
{
gGLLastMatrix = params.mModelMatrix;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
if (params.mModelMatrix)
{
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
}
gPipeline.mMatrixOpCount++;
@@ -461,6 +452,11 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
+ if (!params.mCount)
+ {
+ return;
+ }
+
applyModelMatrix(params);
bool tex_setup = false;
@@ -515,6 +511,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
if (tex_setup)
{
+ gGL.matrixMode(LLRender::MM_TEXTURE0);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index bc299cc89f..ecd9bd034f 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -60,6 +60,7 @@ public:
POOL_GRASS,
POOL_INVISIBLE, // see below *
POOL_AVATAR,
+ POOL_CONTROL_AV, // Animesh
POOL_VOIDWATER,
POOL_WATER,
POOL_GLOW,
@@ -107,16 +108,15 @@ public:
virtual void prerender() = 0;
virtual U32 getVertexDataMask() = 0;
virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
- virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
+ virtual S32 getShaderLevel() const { return mShaderLevel; }
static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
- virtual LLDrawPool *instancePool() = 0; // Create an empty new instance of the pool.
virtual LLViewerTexture* getTexture() = 0;
virtual BOOL isFacePool() { return FALSE; }
virtual void resetDrawOrders() = 0;
protected:
- S32 mVertexShaderLevel;
+ S32 mShaderLevel;
S32 mId;
U32 mType; // Type of draw pool
BOOL mSkipRender;
@@ -138,31 +138,30 @@ public:
PASS_POST_BUMP,
PASS_MATERIAL,
PASS_MATERIAL_ALPHA,
- PASS_MATERIAL_ALPHA_MASK,
+ PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask
PASS_MATERIAL_ALPHA_EMISSIVE,
PASS_SPECMAP,
PASS_SPECMAP_BLEND,
- PASS_SPECMAP_MASK,
+ PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map)
PASS_SPECMAP_EMISSIVE,
PASS_NORMMAP,
PASS_NORMMAP_BLEND,
- PASS_NORMMAP_MASK,
+ PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map
PASS_NORMMAP_EMISSIVE,
PASS_NORMSPEC,
PASS_NORMSPEC_BLEND,
- PASS_NORMSPEC_MASK,
+ PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map
PASS_NORMSPEC_EMISSIVE,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
- PASS_FULLBRIGHT_ALPHA_MASK,
+ PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright
PASS_ALPHA_INVISIBLE,
NUM_RENDER_TYPES,
};
LLRenderPass(const U32 type);
virtual ~LLRenderPass();
- /*virtual*/ LLDrawPool* instancePool();
/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
LLViewerTexture* getTexture() { return NULL; }
BOOL isDead() { return FALSE; }
@@ -174,7 +173,7 @@ public:
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
- virtual void renderTexture(U32 type, U32 mask);
+ virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE);
};
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 0873300cd2..4ee08e869a 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -53,6 +53,22 @@ BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
static BOOL deferred_render = FALSE;
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETUP("Alpha Setup");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED("Alpha Deferred");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SETBUFFER("Alpha SetBuffer");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DRAW("Alpha Draw");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_TEX_BINDS("Alpha Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MATS("Alpha Mat Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GLOW("Alpha Glow Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_SHADER_BINDS("Alpha Shader Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS("Alpha Def Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS("Alpha Def Tex Binds");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MESH_REBUILD("Alpha Mesh Rebuild");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_EMISSIVE("Alpha Emissive");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_LIGHT_SETUP("Alpha Light Setup");
+
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
@@ -69,7 +85,7 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
void LLDrawPoolAlpha::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
@@ -90,37 +106,37 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+
+ emissive_shader->bind();
+ emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
+ emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ emissive_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
if (pass == 0)
{
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gDeferredAlphaImpostorProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gDeferredAlphaWaterProgram;
- fullbright_shader = &gDeferredFullbrightWaterProgram;
- }
- else
- {
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gDeferredFullbrightProgram;
- }
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
fullbright_shader->unbind();
+ simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
}
else if (!LLPipeline::sImpostorRender)
{
@@ -134,25 +150,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
-
- if (LLPipeline::sRenderDeferred)
- {
- emissive_shader = &gDeferredEmissiveProgram;
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- emissive_shader = &gObjectEmissiveProgram;
- }
- }
-
deferred_render = TRUE;
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
// Start out with no shaders.
current_shader = target_shader = NULL;
@@ -162,6 +161,8 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
+
if (pass == 1 && !LLPipeline::sImpostorRender)
{
gPipeline.mDeferredDepth.flush();
@@ -175,44 +176,64 @@ void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
render(pass);
}
void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gObjectSimpleImpostorProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectSimpleWaterProgram;
- fullbright_shader = &gObjectFullbrightWaterProgram;
- emissive_shader = &gObjectEmissiveWaterProgram;
- }
- else
- {
- simple_shader = &gObjectSimpleProgram;
- fullbright_shader = &gObjectFullbrightProgram;
- emissive_shader = &gObjectEmissiveProgram;
- }
+ simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
- if (mVertexShaderLevel > 0)
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+
+ emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+
+ if (LLPipeline::sImpostorRender)
{
- // Start out with no shaders.
- current_shader = target_shader = NULL;
- LLGLSLShader::bindNoShader();
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.5f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.5f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
+ }
}
+ else
+ {
+ if (mShaderLevel > 0)
+ {
+ fullbright_shader->bind();
+ fullbright_shader->setMinimumAlpha(0.f);
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.f);
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+ }
gPipeline.enableLightsDynamic();
+
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
}
void LLDrawPoolAlpha::endRenderPass( S32 pass )
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
LLRenderPass::endRenderPass(pass);
if(gPipeline.canUseWindLightShaders())
@@ -255,38 +276,9 @@ void LLDrawPoolAlpha::render(S32 pass)
mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- if (mVertexShaderLevel > 0)
- {
- if (LLPipeline::sImpostorRender)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.5f);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.5f);
- }
- else
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.f);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.f);
- }
- }
- else
- {
- if (LLPipeline::sImpostorRender)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
- }
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
@@ -311,7 +303,7 @@ void LLDrawPoolAlpha::render(S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
}
gGL.diffuseColor4f(1,0,0,1);
@@ -322,11 +314,15 @@ void LLDrawPoolAlpha::render(S32 pass)
LLVertexBuffer::MAP_TEXCOORD0);
pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ // Material alpha mask
gGL.diffuseColor4f(0, 0, 1, 1);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_NORMMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_SPECMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
gGL.diffuseColor4f(0, 1, 0, 1);
pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
@@ -370,11 +366,257 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
+inline bool IsFullbright(LLDrawInfo& params)
+{
+ return params.mFullbright;
+}
+
+inline bool IsMaterial(LLDrawInfo& params)
+{
+ return params.mMaterial != nullptr;
+}
+
+inline bool IsEmissive(LLDrawInfo& params)
+{
+ return params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
+}
+
+inline void Draw(LLDrawInfo* draw, U32 mask)
+{
+ draw->mVertexBuffer->setBuffer(mask);
+ LLRenderPass::applyModelMatrix(*draw);
+ draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+}
+
+bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader)
+{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_TEX_BINDS);
+
+ bool tex_setup = false;
+
+ if (deferred_render && use_material && current_shader)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
+ 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);
+ }
+ }
+ else if (current_shader == simple_shader)
+ {
+ LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(draw->mVSize);
+ LLViewerFetchedTexture::sWhiteImagep->addTextureStats(draw->mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (use_shaders && draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bind(draw->mTextureList[i], TRUE);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ draw->mTexture->addTextureStats(draw->mVSize);
+ if (use_shaders && use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(draw->mTexture, TRUE) ;
+ }
+
+ 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)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ return tex_setup;
+}
+
+void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
+{
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
+
+void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
+{
+ gPipeline.enableLightsDynamic();
+ simple_shader->bind();
+ simple_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
+ simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
+ simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : simples)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, simple_shader);
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+ simple_shader->unbind();
+}
+
+void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights)
+{
+ gPipeline.enableLightsFullbright();
+ fullbright_shader->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : fullbrights)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, fullbright_shader);
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2));
+ RestoreTexSetup(tex_setup);
+ }
+ fullbright_shader->unbind();
+}
+
+void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
+{
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
+
+ gPipeline.enableLightsDynamic();
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : materials)
+ {
+ U32 mask = draw->mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = (LLPipeline::sUnderWaterRender) ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]);
+
+ if (current_shader != target_shader)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
+ if (current_shader)
+ {
+ gPipeline.unbindDeferredShader(*current_shader);
+ }
+ gPipeline.bindDeferredShader(*target_shader);
+ current_shader = target_shader;
+ }
+
+ bool tex_setup = TexSetup(draw, use_shaders, true, current_shader);
+
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, draw->mSpecColor.mV[0], draw->mSpecColor.mV[1], draw->mSpecColor.mV[2], draw->mSpecColor.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, draw->mEnvIntensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, draw->mFullbright ? 1.f : 0.f);
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_TEX_BINDS);
+ 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);
+ }
+ }
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, draw->mSelected, &LLGLCommonFunc::selected_stencil_test);
+ gGL.blendFunc((LLRender::eBlendFactor) draw->mBlendFuncSrc, (LLRender::eBlendFactor) draw->mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+
+ Draw(draw, mask);
+ RestoreTexSetup(tex_setup);
+ }
+}
+
+void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
+{
+ draw->mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
+ draw->mVertexBuffer->drawRange(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ gPipeline.addTrianglesDrawn(draw->mCount, draw->mDrawMode);
+}
+
+void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw)
+{
+ // install glow-accumulating blend mode
+ gGL.blendFunc(
+ LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
+ LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+
+ emissive_shader->bind();
+
+ drawEmissive(mask, draw);
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ current_shader->bind();
+}
+
+void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+{
+ emissive_shader->bind();
+ emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
+
+ gPipeline.enableLightsDynamic();
+
+ // install glow-accumulating blend mode
+ // don't touch color, add to alpha (glow)
+ gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE);
+ bool use_shaders = gPipeline.canUseVertexShaders();
+ for (LLDrawInfo* draw : emissives)
+ {
+ bool tex_setup = TexSetup(draw, use_shaders, false, emissive_shader);
+ drawEmissive(mask, draw);
+ RestoreTexSetup(tex_setup);
+ }
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ emissive_shader->unbind();
+}
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
+ BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
+ BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
@@ -389,10 +631,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
+ std::vector<LLDrawInfo*> emissives;
+ std::vector<LLDrawInfo*> fullbrights;
+
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
- bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
+ bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP);
@@ -405,11 +650,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
-
- if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
+ if (have_mask != mask)
{ //FIXME!
LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
- << " present: " << (params.mVertexBuffer->getTypeMask() & mask)
+ << " present: " << have_mask
<< ". Skipping render batch." << LL_ENDL;
continue;
}
@@ -431,6 +676,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
}
+ if (params.mFullbright && batch_fullbrights)
+ {
+ fullbrights.push_back(&params);
+ continue;
+ }
+
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
@@ -445,6 +696,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
// Turn off lighting if it hasn't already been so.
if (light_enabled || !initialized_lighting)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
+
initialized_lighting = TRUE;
if (use_shaders)
{
@@ -452,7 +705,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
}
light_enabled = FALSE;
}
@@ -460,6 +713,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
// Turn on lighting if it isn't already.
else if (!light_enabled || !initialized_lighting)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_LIGHT_SETUP);
+
initialized_lighting = TRUE;
if (use_shaders)
{
@@ -486,7 +741,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (current_shader != target_shader)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
gPipeline.bindDeferredShader(*target_shader);
+ current_shader = target_shader;
}
}
else if (!params.mFullbright)
@@ -501,6 +758,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if(use_shaders && (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).
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SHADER_BINDS);
current_shader = target_shader;
current_shader->bind();
}
@@ -510,83 +768,31 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
current_shader = NULL;
}
- if (use_shaders && mat)
- {
- // We have a material. Supply the appropriate data here.
- if (LLPipeline::sRenderDeferred)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+ LLVector4 spec_color(1, 1, 1, 1);
+ F32 env_intensity = 0.0f;
+ F32 brightness = 1.0f;
- if (params.mNormalMap)
- {
- params.mNormalMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
- }
-
- if (params.mSpecularMap)
- {
- params.mSpecularMap->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
- }
- }
-
- } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
+ // We have a material. Supply the appropriate data here.
+ if (use_shaders && mat && deferred_render)
{
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
- LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
+ 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 (params.mGroup)
{
params.mGroup->rebuildMesh();
}
- bool tex_setup = false;
-
- if (use_shaders && params.mTextureList.size() > 1)
- {
- for (U32 i = 0; i < params.mTextureList.size(); ++i)
- {
- if (params.mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTexture.notNull())
- {
- params.mTexture->addTextureStats(params.mVSize);
- if (use_shaders && mat)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
- }
-
- if (params.mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
+ bool tex_setup = TexSetup(&params, use_shaders, use_shaders && (mat != nullptr), current_shader);
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
@@ -596,41 +802,56 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DRAW);
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ }
}
-
- // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
+
+ // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
if (current_shader &&
draw_glow_for_this_partition &&
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
- // install glow-accumulating blend mode
- gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
-
- emissive_shader->bind();
-
- params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
-
- // do the actual drawing, again
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
-
- // restore our alpha blend mode
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- current_shader->bind();
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE);
+
+ if (batch_emissives)
+ {
+ emissives.push_back(&params);
+ }
+ else
+ {
+ drawEmissiveInline(mask, &params);
+ }
}
if (tex_setup)
{
gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
- }
+
+ if (batch_fullbrights)
+ {
+ light_enabled = false;
+ renderFullbrights(mask, fullbrights);
+ }
+
+ if (batch_emissives)
+ {
+ light_enabled = true;
+ renderEmissives(mask, emissives);
+ }
+
+ if (current_shader)
+ {
+ current_shader->bind();
+ }
+ }
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index d064a3a324..a069f805e8 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -75,6 +75,17 @@ private:
LLGLSLShader* fullbright_shader;
LLGLSLShader* emissive_shader;
+ void renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples);
+ void renderFullbrights(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
+ void renderMaterials(U32 mask, std::vector<LLDrawInfo*>& fullbrights);
+ void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
+
+ void drawEmissive(U32 mask, LLDrawInfo* draw);
+ void drawEmissiveInline(U32 mask, LLDrawInfo* draw);
+
+ bool TexSetup(LLDrawInfo* draw, bool use_shaders, bool use_material, LLGLSLShader* current_shader);
+ void RestoreTexSetup(bool tex_setup);
+
// our 'normal' alpha blend function for this pass
LLRender::eBlendFactor mColorSFactor;
LLRender::eBlendFactor mColorDFactor;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 63abadbcf4..687b13d2c8 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -105,8 +105,8 @@ S32 cube_channel = -1;
static LLTrace::BlockTimerStatHandle FTM_SHADOW_AVATAR("Avatar Shadow");
-LLDrawPoolAvatar::LLDrawPoolAvatar() :
- LLFacePool(POOL_AVATAR)
+LLDrawPoolAvatar::LLDrawPoolAvatar(U32 type) :
+ LLFacePool(type)
{
}
@@ -135,26 +135,17 @@ BOOL LLDrawPoolAvatar::isDead()
}
return TRUE;
}
-
-//-----------------------------------------------------------------------------
-// instancePool()
-//-----------------------------------------------------------------------------
-LLDrawPool *LLDrawPoolAvatar::instancePool()
-{
- return new LLDrawPoolAvatar();
-}
-
-S32 LLDrawPoolAvatar::getVertexShaderLevel() const
+S32 LLDrawPoolAvatar::getShaderLevel() const
{
- return (S32) LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ return (S32) LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
}
void LLDrawPoolAvatar::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sShaderLevel > 0)
{
@@ -305,7 +296,7 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
void LLDrawPoolAvatar::beginPostDeferredAlpha()
{
sSkipOpaque = TRUE;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarAlphaProgram;
sRenderingSkinned = TRUE;
@@ -396,7 +387,7 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
@@ -455,8 +446,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+
if ((sShaderLevel > 0)) // for hardware blending
{
sRenderingSkinned = TRUE;
@@ -470,8 +466,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAvatarAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+
if ((sShaderLevel > 0)) // for hardware blending
{
sRenderingSkinned = TRUE;
@@ -485,7 +486,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -500,7 +506,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
// bind diffuse tex so we can reference the alpha channel...
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
if ((sShaderLevel > 0)) // for hardware blending
{
@@ -513,7 +524,12 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
else // SHADOW_PASS_ATTACHMENT_OPAQUE
{
sVertexProgram = &gDeferredAttachmentShadowProgram;
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 loc = sVertexProgram->getUniformLocation(LLViewerShaderMgr::DIFFUSE_MAP);
+ sDiffuseChannel = 0;
+ if (loc != -1)
+ {
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
sVertexProgram->bind();
}
}
@@ -556,12 +572,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{
return;
}
-
- BOOL impostor = avatarp->isImpostor();
- if (impostor
- && LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings()
- && LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings())
+ LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
+ if (oa == LLVOAvatar::AOA_INVISIBLE ||
+ (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
{
+ // No shadows for jellydolled or invisible avs.
return;
}
@@ -776,7 +792,7 @@ void LLDrawPoolAvatar::beginImpostor()
gImpostorProgram.setMinimumAlpha(0.01f);
}
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
sDiffuseChannel = 0;
}
@@ -806,6 +822,14 @@ void LLDrawPoolAvatar::beginRigid()
{ //eyeballs render with the specular shader
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
else
@@ -816,7 +840,7 @@ void LLDrawPoolAvatar::beginRigid()
void LLDrawPoolAvatar::endRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
if (sVertexProgram != NULL)
{
sVertexProgram->unbind();
@@ -841,7 +865,7 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
void LLDrawPoolAvatar::endDeferredImpostor()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -856,11 +880,19 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRigid()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
gGL.getTexUnit(0)->activate();
@@ -899,6 +931,14 @@ void LLDrawPoolAvatar::beginSkinned()
sVertexProgram->bind();
sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
gGL.getTexUnit(0)->activate();
}
else
@@ -908,6 +948,14 @@ void LLDrawPoolAvatar::beginSkinned()
// software skinning, use a basic shader for windlight.
// TODO: find a better fallback method for software skinning.
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -926,7 +974,7 @@ void LLDrawPoolAvatar::endSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
gGL.getTexUnit(0)->activate();
sVertexProgram->unbind();
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
}
else
{
@@ -970,6 +1018,14 @@ void LLDrawPoolAvatar::beginRiggedSimple()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -1035,6 +1091,16 @@ void LLDrawPoolAvatar::beginRiggedGlow()
sVertexProgram->bind();
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
@@ -1082,16 +1148,22 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
sDiffuseChannel = 0;
sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
else
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1134,6 +1206,14 @@ void LLDrawPoolAvatar::beginRiggedShinySimple()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
}
}
@@ -1184,17 +1264,32 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderingHUDs)
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
{
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
}
@@ -1216,6 +1311,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedSimple()
sVertexProgram = &gDeferredSkinnedDiffuseProgram;
sDiffuseChannel = 0;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolAvatar::endDeferredRiggedSimple()
@@ -1229,6 +1332,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedBump()
{
sVertexProgram = &gDeferredSkinnedBumpProgram;
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -1261,6 +1372,14 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
}
sVertexProgram->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -1288,13 +1407,21 @@ void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
void LLDrawPoolAvatar::beginDeferredSkinned()
{
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
sRenderingSkinned = TRUE;
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
-
+ if (LLPipeline::sRenderingHUDs)
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
}
@@ -1307,7 +1434,7 @@ void LLDrawPoolAvatar::endDeferredSkinned()
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sShaderLevel = mVertexShaderLevel;
+ sShaderLevel = mShaderLevel;
gGL.getTexUnit(0)->activate();
}
@@ -1337,7 +1464,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- LLVOAvatar *avatarp;
+ LLVOAvatar *avatarp = NULL;
if (single_avatar)
{
@@ -1383,11 +1510,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- BOOL impostor = avatarp->isImpostor() && !single_avatar;
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;
if (( avatarp->isInMuteList()
|| impostor
- || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+ || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+// || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
{ //don't draw anything but the impostor for impostored avatars
return;
}
@@ -1397,6 +1525,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
+ LLVOAvatar *attached_av = avatarp->getAttachedAvatar();
+ if (attached_av && LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance())
+ {
+ // Animesh attachment of a jellydolled or invisible parent - don't show
+ return;
+ }
+
if (pass == 0)
{
if (!LLPipeline::sReflectionRender)
@@ -1404,7 +1539,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
LLVOAvatar::sNumVisibleAvatars++;
}
- if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+// if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+ if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))
{
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())
{
@@ -1604,11 +1740,16 @@ void LLDrawPoolAvatar::getRiggedGeometry(
LLVolume* volume,
const LLVolumeFace& vol_face)
{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
-
- //rigged faces do not batch textures
- face->setTextureIndex(255);
+ face->setGeomIndex(0);
+ face->setIndicesIndex(0);
+
+ if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES)
+ {
+ face->setDrawInfo(NULL);
+ }
+
+ //rigged faces do not batch textures
+ face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
{
@@ -1673,7 +1814,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(
}
else
{
- face->setPoolType(LLDrawPool::POOL_AVATAR);
+ face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV
}
//LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL;
@@ -1697,15 +1838,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLFace* face,
const LLMeshSkinInfo* skin,
LLVolume* volume,
- const LLVolumeFace& vol_face)
+ LLVolumeFace& vol_face)
{
LLVector4a* weights = vol_face.mWeights;
if (!weights)
{
return;
}
- // FIXME ugly const cast
- LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
@@ -1715,6 +1854,48 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
+ const U32 max_joints = LLSkinningUtil::getMaxJointCount();
+
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ #define CONDITION_WEIGHT(f) ((U8)llclamp((S32)f, (S32)0, (S32)max_joints-1))
+ LLVector4a* just_weights = vol_face.mJustWeights;
+ // we need to calculate the separated indices and store just the matrix weights for this vol...
+ if (!vol_face.mJointIndices)
+ {
+ // not very consty after all...
+ vol_face.allocateJointIndices(vol_face.mNumVertices);
+ just_weights = vol_face.mJustWeights;
+
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ for (int i = 0; i < vol_face.mNumVertices; i++)
+ {
+ F32* w = weights[i].getF32ptr();
+ F32* w_ = just_weights[i].getF32ptr();
+
+ F32 w0 = floorf(w[0]);
+ F32 w1 = floorf(w[1]);
+ F32 w2 = floorf(w[2]);
+ F32 w3 = floorf(w[3]);
+
+ joint_indices_cursor[0] = CONDITION_WEIGHT(w0);
+ joint_indices_cursor[1] = CONDITION_WEIGHT(w1);
+ joint_indices_cursor[2] = CONDITION_WEIGHT(w2);
+ joint_indices_cursor[3] = CONDITION_WEIGHT(w3);
+
+ // remove joint portion of combined weight
+ w_[0] = w[0] - w0;
+ w_[1] = w[1] - w1;
+ w_[2] = w[2] - w2;
+ w_[3] = w[3] - w3;
+
+ joint_indices_cursor += 4;
+ }
+ }
+#endif
+
+ // FIXME ugly const cast
+ LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
+
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
@@ -1791,29 +1972,67 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
- const U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
- LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
-
- LLVector4a& v = vol_face.mPositions[j];
-
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
-
- if (norm)
- {
- LLVector4a& n = vol_face.mNormals[j];
- bind_shape_matrix.rotate(n, t);
- final_mat.rotate(t, dst);
- dst.normalize3fast();
- norm[j] = dst;
- }
- }
+#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ // fast path with joint indices separate from weights
+ if (joint_indices_cursor)
+ {
+ LLMatrix4a src[4];
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ //LLMatrix4a final_mat_correct;
+
+ F32* jw = just_weights[j].getF32ptr();
+
+ LLSkinningUtil::getPerVertexSkinMatrixWithIndices(jw, joint_indices_cursor, mat, final_mat, src);
+
+ joint_indices_cursor += 4;
+
+ LLVector4a& v = vol_face.mPositions[j];
+
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+
+ if (norm)
+ {
+ LLVector4a& n = vol_face.mNormals[j];
+ bind_shape_matrix.rotate(n, t);
+ final_mat.rotate(t, dst);
+ dst.normalize3fast();
+ norm[j] = dst;
+ }
+ }
+ }
+ // slow path with joint indices calculated from weights
+ else
+#endif
+ {
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
+
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+
+ if (norm)
+ {
+ LLVector4a& n = vol_face.mNormals[j];
+ bind_shape_matrix.rotate(n, t);
+ final_mat.rotate(t, dst);
+ //dst.normalize3fast();
+ norm[j] = dst;
+ }
+ }
+ }
}
}
@@ -2079,12 +2298,24 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (face->mTextureMatrix && vobj->mTexAnimMode)
{
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ U32 tex_index = gGL.getCurrentTexUnitIndex();
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.pushMatrix();
+ gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
+ }
+
buff->setBuffer(data_mask);
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ if (tex_index <= 1)
+ {
+ gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
else
{
@@ -2153,7 +2384,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
stop_glerror();
- const LLVolumeFace& vol_face = volume->getVolumeFace(te);
+ LLVolumeFace& vol_face = volume->getVolumeFace(te);
updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
}
}
@@ -2267,7 +2498,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
{
llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR);
+ llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() && facep->getPool() != this)
{
LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL;
@@ -2289,7 +2520,7 @@ void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
{
llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR);
+ llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
if (facep->getPool() != this)
{
LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL;
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 8c1bc70c8e..92a8538958 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -57,6 +57,7 @@ public:
~LLDrawPoolAvatar();
/*virtual*/ BOOL isDead();
+
typedef enum
{
RIGGED_MATERIAL=0,
@@ -175,14 +176,12 @@ typedef enum
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- virtual S32 getVertexShaderLevel() const;
+ virtual S32 getShaderLevel() const;
- LLDrawPoolAvatar();
+ LLDrawPoolAvatar(U32 type);
static LLMatrix4& getModelView();
- /*virtual*/ LLDrawPool *instancePool();
-
/*virtual*/ S32 getNumPasses();
/*virtual*/ void beginRenderPass(S32 pass);
/*virtual*/ void endRenderPass(S32 pass);
@@ -256,7 +255,7 @@ typedef enum
LLFace* facep,
const LLMeshSkinInfo* skin,
LLVolume* volume,
- const LLVolumeFace& vol_face);
+ LLVolumeFace& vol_face);
void updateRiggedVertexBuffers(LLVOAvatar* avatar);
void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 7b9fd5c6c6..14069fa6c2 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -193,7 +193,7 @@ LLDrawPoolBump::LLDrawPoolBump()
void LLDrawPoolBump::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
// static
@@ -201,7 +201,7 @@ S32 LLDrawPoolBump::numBumpPasses()
{
if (gSavedSettings.getBOOL("RenderObjectBump"))
{
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
if (LLPipeline::sImpostorRender)
{
@@ -241,7 +241,7 @@ void LLDrawPoolBump::beginRenderPass(S32 pass)
beginShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
beginFullbrightShiny();
}
@@ -274,7 +274,7 @@ void LLDrawPoolBump::render(S32 pass)
renderShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
renderFullbrightShiny();
}
@@ -301,7 +301,7 @@ void LLDrawPoolBump::endRenderPass(S32 pass)
endShiny();
break;
case 1:
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
endFullbrightShiny();
}
@@ -335,12 +335,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)
mShiny = TRUE;
sVertexMask = VERTEX_MASK_SHINY;
// Second pass: environment map
- if (!invisible && mVertexShaderLevel > 1)
+ if (!invisible && mShaderLevel > 1)
{
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
}
- if (getVertexShaderLevel() > 0)
+ if (getShaderLevel() > 0)
{
if (LLPipeline::sUnderWaterRender)
{
@@ -351,15 +351,23 @@ void LLDrawPoolBump::beginShiny(bool invisible)
shader = &gObjectShinyProgram;
}
shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
shader = NULL;
}
- bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
+ bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
diffuse_channel = 0;
}
@@ -428,7 +436,7 @@ void LLDrawPoolBump::renderShiny(bool invisible)
if( gSky.mVOSkyp->getCubeMap() )
{
LLGLEnable blend_enable(GL_BLEND);
- if (!invisible && mVertexShaderLevel > 1)
+ if (!invisible && mShaderLevel > 1)
{
LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
@@ -453,7 +461,7 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
{
if (diffuse_channel != 0)
{
@@ -486,7 +494,7 @@ void LLDrawPoolBump::endShiny(bool invisible)
return;
}
- unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible);
+ unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
if (shader)
{
shader->unbind();
@@ -534,6 +542,15 @@ void LLDrawPoolBump::beginFullbrightShiny()
LLVector4(gGLModelView+8),
LLVector4(gGLModelView+12));
shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
@@ -551,7 +568,7 @@ void LLDrawPoolBump::beginFullbrightShiny()
gGL.getTexUnit(0)->activate();
}
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
diffuse_channel = 0;
}
@@ -571,7 +588,7 @@ void LLDrawPoolBump::renderFullbrightShiny()
{
LLGLEnable blend_enable(GL_BLEND);
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{
LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
@@ -1524,7 +1541,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
tex_setup = true;
}
- if (mShiny && mVertexShaderLevel > 1 && texture)
+ if (mShiny && mShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 59c3fbf7a1..5b74264dab 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -46,14 +46,9 @@ LLDrawPoolGround::LLDrawPoolGround() :
{
}
-LLDrawPool *LLDrawPoolGround::instancePool()
-{
- return new LLDrawPoolGround();
-}
-
void LLDrawPoolGround::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
}
void LLDrawPoolGround::render(S32 pass)
@@ -63,13 +58,9 @@ void LLDrawPoolGround::render(S32 pass)
return;
}
- LLGLSPipelineSkyBox gls_skybox;
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
F32 water_height = gAgent.getRegion()->getWaterHeight();
gGL.pushMatrix();
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
@@ -77,8 +68,6 @@ void LLDrawPoolGround::render(S32 pass)
LLFace *facep = mDrawFace[0];
- gPipeline.disableLights();
-
LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
facep->renderIndexed();
diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h
index a4f8a3fcf5..15b1dc60a2 100644
--- a/indra/newview/lldrawpoolground.h
+++ b/indra/newview/lldrawpoolground.h
@@ -43,8 +43,6 @@ public:
LLDrawPoolGround();
- /*virtual*/ LLDrawPool *instancePool();
-
/*virtual*/ void prerender();
/*virtual*/ void render(S32 pass = 0);
};
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 63e96a93b5..05b0c1f1a9 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -42,7 +42,7 @@ LLDrawPoolMaterials::LLDrawPoolMaterials()
void LLDrawPoolMaterials::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolMaterials::getNumDeferredPasses()
@@ -81,6 +81,15 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
mShader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ mShader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ mShader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
LL_RECORD_BLOCK_TIME(FTM_RENDER_MATERIALS);
@@ -194,7 +203,7 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
tex_setup = true;
}
- if (mVertexShaderLevel > 1 && texture)
+ if (mShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index bd180de6c6..f211cf6e27 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -47,6 +47,14 @@ void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
{
gDeferredEmissiveProgram.bind();
gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -82,7 +90,7 @@ void LLDrawPoolGlow::endPostDeferredPass(S32 pass)
S32 LLDrawPoolGlow::getNumPasses()
{
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
{
return 1;
}
@@ -103,7 +111,7 @@ void LLDrawPoolGlow::render(S32 pass)
glPolygonOffset(-1.0f, -1.0f);
gGL.setSceneBlendType(LLRender::BT_ADD);
- U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
//should never get here without basic shaders enabled
llassert(shader_level > 0);
@@ -119,6 +127,15 @@ void LLDrawPoolGlow::render(S32 pass)
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
}
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@@ -147,7 +164,7 @@ LLDrawPoolSimple::LLDrawPoolSimple() :
void LLDrawPoolSimple::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolSimple::beginRenderPass(S32 pass)
@@ -167,9 +184,18 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
simple_shader = &gObjectSimpleProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -187,7 +213,7 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -201,7 +227,7 @@ void LLDrawPoolSimple::render(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
gPipeline.enableLightsDynamic();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
@@ -244,7 +270,7 @@ LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
void LLDrawPoolAlphaMask::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
@@ -260,9 +286,18 @@ void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
simple_shader = &gObjectSimpleAlphaMaskProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -280,7 +315,7 @@ void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -291,11 +326,20 @@ void LLDrawPoolAlphaMask::render(S32 pass)
LLGLDisable blend(GL_BLEND);
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
@@ -317,7 +361,7 @@ LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
void LLDrawPoolFullbrightAlphaMask::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
@@ -333,9 +377,18 @@ void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
simple_shader = &gObjectFullbrightAlphaMaskProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -353,7 +406,7 @@ void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -363,18 +416,30 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
if (simple_shader)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
- {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- } else {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- }
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ if (LLPipeline::sRenderDeferred)
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ }
}
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
//LLGLSLShader::bindNoShader();
@@ -382,7 +447,7 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
else
{
LLGLEnable test(GL_ALPHA_TEST);
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
gPipeline.enableLightsDynamic();
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
@@ -397,6 +462,15 @@ void LLDrawPoolSimple::beginDeferredPass(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
gDeferredDiffuseProgram.bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
void LLDrawPoolSimple::endDeferredPass(S32 pass)
@@ -435,6 +509,16 @@ void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED);
gDeferredDiffuseAlphaMaskProgram.bind();
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
gDeferredDiffuseAlphaMaskProgram.unbind();
}
@@ -449,7 +533,7 @@ LLDrawPoolGrass::LLDrawPoolGrass() :
void LLDrawPoolGrass::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
@@ -467,10 +551,18 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
simple_shader = &gObjectAlphaMaskNonIndexedProgram;
}
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.5f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
else
{
@@ -488,7 +580,7 @@ void LLDrawPoolGrass::endRenderPass(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);
LLRenderPass::endRenderPass(pass);
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
simple_shader->unbind();
}
@@ -527,6 +619,16 @@ void LLDrawPoolGrass::renderDeferred(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS_DEFERRED);
gDeferredNonIndexedDiffuseAlphaMaskProgram.bind();
gDeferredNonIndexedDiffuseAlphaMaskProgram.setMinimumAlpha(0.5f);
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
//render grass
LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
}
@@ -541,7 +643,7 @@ LLDrawPoolFullbright::LLDrawPoolFullbright() :
void LLDrawPoolFullbright::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
@@ -553,6 +655,15 @@ void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
else
{
gDeferredFullbrightProgram.bind();
+
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
}
@@ -600,7 +711,7 @@ void LLDrawPoolFullbright::endRenderPass(S32 pass)
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
fullbright_shader->unbind();
}
@@ -615,12 +726,21 @@ void LLDrawPoolFullbright::render(S32 pass)
stop_glerror();
- if (mVertexShaderLevel > 0)
+ if (mShaderLevel > 0)
{
fullbright_shader->bind();
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
+ if (LLPipeline::sRenderingHUDs)
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
@@ -630,7 +750,7 @@ void LLDrawPoolFullbright::render(S32 pass)
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsFullbright();
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
@@ -651,23 +771,32 @@ S32 LLDrawPoolFullbright::getNumPasses()
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
{
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
- {
- gObjectFullbrightAlphaMaskProgram.bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
+ gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else if (LLPipeline::sRenderDeferred)
+ {
+ if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.bind();
gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
}
else
{
gDeferredFullbrightAlphaMaskProgram.bind();
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
}
+ }
+ else
+ {
+ gObjectFullbrightAlphaMaskProgram.bind();
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
}
}
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index bdb16abc78..b6f55e800a 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -48,14 +48,9 @@ LLDrawPoolSky::LLDrawPoolSky()
{
}
-LLDrawPool *LLDrawPoolSky::instancePool()
-{
- return new LLDrawPoolSky();
-}
-
void LLDrawPoolSky::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
}
@@ -75,7 +70,7 @@ void LLDrawPoolSky::render(S32 pass)
}
// don't render sky under water (background just gets cleared to fog color)
- if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender)
+ if(mShaderLevel > 0 && LLPipeline::sUnderWaterRender)
{
return;
}
@@ -98,18 +93,10 @@ void LLDrawPoolSky::render(S32 pass)
}
- LLGLSPipelineSkyBox gls_skybox;
-
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
- LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
- gPipeline.disableLights();
+ LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
- LLGLDisable clip(GL_CLIP_PLANE0);
-
gGL.pushMatrix();
LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
@@ -119,35 +106,41 @@ void LLDrawPoolSky::render(S32 pass)
LLVertexBuffer::unbind();
gGL.diffuseColor4f(1,1,1,1);
- for (S32 i = 0; i < llmin(6, face_count); ++i)
+ for (S32 i = 0; i < face_count; ++i)
{
- renderSkyCubeFace(i);
+ renderSkyFace(i);
}
gGL.popMatrix();
}
-void LLDrawPoolSky::renderSkyCubeFace(U8 side)
+void LLDrawPoolSky::renderSkyFace(U8 index)
{
- LLFace &face = *mDrawFace[LLVOSky::FACE_SIDE0 + side];
- if (!face.getGeomCount())
+ LLFace* face = mDrawFace[index];
+
+ if (!face || !face->getGeomCount())
{
return;
}
- llassert(mSkyTex);
- mSkyTex[side].bindTexture(TRUE);
-
- face.renderIndexed();
-
- if (LLSkyTex::doInterpolate())
- {
-
- LLGLEnable blend(GL_BLEND);
- mSkyTex[side].bindTexture(FALSE);
- gGL.diffuseColor4f(1, 1, 1, LLSkyTex::getInterpVal()); // lighting is disabled
- face.renderIndexed();
- }
+ if (index < 6) // sky tex...interp
+ {
+ llassert(mSkyTex);
+ mSkyTex[index].bindTexture(true); // bind the current tex
+
+ face->renderIndexed();
+ }
+ else // heavenly body faces, no interp...
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
+ if (tex)
+ {
+ gGL.getTexUnit(0)->bind(tex, true);
+ face->renderIndexed();
+ }
+ }
}
void LLDrawPoolSky::endRenderPass( S32 pass )
diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index 098bd2134a..d1dcd6b22e 100644
--- a/indra/newview/lldrawpoolsky.h
+++ b/indra/newview/lldrawpoolsky.h
@@ -49,8 +49,6 @@ public:
LLDrawPoolSky();
- /*virtual*/ LLDrawPool *instancePool();
-
/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); }
/*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); }
/*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); }
@@ -61,7 +59,7 @@ public:
/*virtual*/ void endRenderPass(S32 pass);
void setSkyTex(LLSkyTex* const st) { mSkyTex = st; }
- void renderSkyCubeFace(U8 side);
+ void renderSkyFace(U8 index);
void renderHeavenlyBody(U8 hb, LLFace* face);
void renderSunHalo(LLFace* face);
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 3eefcef7aa..37dc80e2b7 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -48,6 +48,8 @@
#include "pipeline.h"
#include "llviewershadermgr.h"
#include "llrender.h"
+#include "llenvironment.h"
+#include "llsettingsvo.h"
const F32 DETAIL_SCALE = 1.f/16.f;
int DebugDetailMap = 0;
@@ -85,13 +87,6 @@ LLDrawPoolTerrain::~LLDrawPoolTerrain()
llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
}
-
-LLDrawPool *LLDrawPoolTerrain::instancePool()
-{
- return new LLDrawPoolTerrain(mTexturep);
-}
-
-
U32 LLDrawPoolTerrain::getVertexDataMask()
{
if (LLPipeline::sShadowRender)
@@ -110,7 +105,7 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
void LLDrawPoolTerrain::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
}
@@ -123,7 +118,7 @@ void LLDrawPoolTerrain::beginRenderPass( S32 pass )
&gTerrainWaterProgram :
&gTerrainProgram;
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
{
sShader->bind();
}
@@ -134,7 +129,7 @@ void LLDrawPoolTerrain::endRenderPass( S32 pass )
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
//LLFacePool::endRenderPass(pass);
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) {
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0) {
sShader->unbind();
}
}
@@ -145,6 +140,18 @@ S32 LLDrawPoolTerrain::getDetailMode()
return sDetailMode;
}
+void LLDrawPoolTerrain::boostTerrainDetailTextures()
+{
+ // Hack! Get the region that this draw pool is rendering from!
+ LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
+ LLVLComposition *compp = regionp->getComposition();
+ for (S32 i = 0; i < 4; i++)
+ {
+ compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
+ compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
+ }
+}
+
void LLDrawPoolTerrain::render(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
@@ -154,14 +161,7 @@ void LLDrawPoolTerrain::render(S32 pass)
return;
}
- // Hack! Get the region that this draw pool is rendering from!
- LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
- LLVLComposition *compp = regionp->getComposition();
- for (S32 i = 0; i < 4; i++)
- {
- compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
- }
+ boostTerrainDetailTextures();
LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
@@ -180,7 +180,7 @@ void LLDrawPoolTerrain::render(S32 pass)
LLGLSPipeline gls;
- if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0)
+ if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
{
gPipeline.enableLightsDynamic();
@@ -216,7 +216,7 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
- sShader = &gDeferredTerrainProgram;
+ sShader = LLPipeline::sUnderWaterRender ? &gDeferredTerrainWaterProgram : &gDeferredTerrainProgram;
sShader->bind();
}
@@ -236,6 +236,8 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass)
return;
}
+ boostTerrainDetailTextures();
+
renderFullShader();
// Special-case for land ownership feedback
@@ -252,6 +254,9 @@ void LLDrawPoolTerrain::beginShadowPass(S32 pass)
LLFacePool::beginRenderPass(pass);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredShadowProgram.bind();
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
void LLDrawPoolTerrain::endShadowPass(S32 pass)
@@ -327,7 +332,8 @@ void LLDrawPoolTerrain::renderFullShader()
//
S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
gGL.getTexUnit(detail0)->bind(detail_texture0p);
- gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(detail0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail0)->activate();
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(shader);
@@ -335,54 +341,40 @@ void LLDrawPoolTerrain::renderFullShader()
shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+
+ ((LLSettingsVOWater*)pwater.get())->updateShader(shader);
//
// detail texture 1
//
S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1);
gGL.getTexUnit(detail1)->bind(detail_texture1p);
-
- /// ALPHA TEXTURE COORDS 0:
- gGL.getTexUnit(1)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail1)->activate();
// detail texture 2
//
S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
gGL.getTexUnit(detail2)->bind(detail_texture2p);
-
- gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail2)->activate();
- /// ALPHA TEXTURE COORDS 1:
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-2.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- //
// detail texture 3
//
S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(detail3)->bind(detail_texture3p);
-
- /// ALPHA TEXTURE COORDS 2:
- gGL.getTexUnit(3)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.translatef(-1.f, 0.f, 0.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(detail3)->activate();
//
// Alpha Ramp
//
S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep);
-
+ gGL.getTexUnit(alpha_ramp)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
// GL_BLEND disabled by default
drawLoop();
@@ -394,47 +386,32 @@ void LLDrawPoolTerrain::renderFullShader()
sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(4)->disable();
- gGL.getTexUnit(4)->activate();
+ gGL.getTexUnit(alpha_ramp)->disable();
+ gGL.getTexUnit(alpha_ramp)->activate();
gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(3)->disable();
- gGL.getTexUnit(3)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail3)->disable();
+ gGL.getTexUnit(detail3)->activate();
gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
- gGL.getTexUnit(2)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail2)->disable();
+ gGL.getTexUnit(detail2)->activate();
gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->activate();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail1)->disable();
+ gGL.getTexUnit(detail1)->activate();
//----------------------------------------------------------------------------
// Restore Texture Unit 0 defaults
gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(detail0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(detail0)->activate();
}
void LLDrawPoolTerrain::hilightParcelOwners(bool deferred)
{
- if (mVertexShaderLevel > 1)
+ if (mShaderLevel > 1)
{ //use fullbright shader for highlighting
LLGLSLShader* old_shader = sShader;
sShader->unbind();
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 484820491a..5b4558020d 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -49,8 +49,6 @@ public:
LLDrawPoolTerrain(LLViewerTexture *texturep);
virtual ~LLDrawPoolTerrain();
- /*virtual*/ LLDrawPool *instancePool();
-
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
@@ -78,6 +76,8 @@ public:
static F32 sDetailScale; // meters per texture
protected:
+ void boostTerrainDetailTextures();
+
void renderSimple();
void renderOwnership();
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index b1f40781f7..0d5195bdbf 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -38,6 +38,7 @@
#include "llrender.h"
#include "llviewercontrol.h"
#include "llviewerregion.h"
+#include "llenvironment.h"
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
@@ -50,14 +51,9 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
}
-LLDrawPool *LLDrawPoolTree::instancePool()
-{
- return new LLDrawPoolTree(mTexturep);
-}
-
void LLDrawPoolTree::prerender()
{
- mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+ mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolTree::beginRenderPass(S32 pass)
@@ -96,7 +92,6 @@ void LLDrawPoolTree::render(S32 pass)
}
LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
- LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
gGL.getTexUnit(sDiffTex)->bind(mTexturep);
@@ -138,7 +133,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
shader->unbind();
}
- if (mVertexShaderLevel <= 0)
+ if (mShaderLevel <= 0)
{
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
@@ -178,7 +173,10 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)
glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
+ LLEnvironment& environment = LLEnvironment::instance();
+
gDeferredTreeShadowProgram.bind();
+ gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gDeferredTreeShadowProgram.setMinimumAlpha(0.5f);
}
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index e7e25453cf..13f9ec8dce 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
@@ -37,15 +37,14 @@ public:
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TEXCOORD0
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
LLDrawPoolTree(LLViewerTexture *texturep);
- /*virtual*/ LLDrawPool *instancePool();
-
/*virtual*/ void prerender();
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index df06ad31e6..aa426cd785 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -46,10 +46,9 @@
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
-#include "llwaterparammanager.h"
-
-const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
-const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
+#include "llenvironment.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
static float sTime;
@@ -58,61 +57,56 @@ BOOL deferred_render = FALSE;
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
-LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
-LLVector3 LLDrawPoolWater::sLightDir;
-
-LLDrawPoolWater::LLDrawPoolWater() :
- LLFacePool(POOL_WATER)
+LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
{
- mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- gGL.getTexUnit(0)->bind(mHBTex[0]) ;
- mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- gGL.getTexUnit(0)->bind(mHBTex[1]);
- mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-
- mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
- llassert(mWaterImagep);
- mWaterImagep->setNoDelete();
- mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
- llassert(mOpaqueWaterImagep);
- mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
- mWaterNormp->setNoDelete();
-
- restoreGL();
}
LLDrawPoolWater::~LLDrawPoolWater()
{
}
-//static
-void LLDrawPoolWater::restoreGL()
+void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId)
{
-
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId());
+ mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()));
+ mWaterImagep[0]->addTextureStats(1024.f*1024.f);
+ mWaterImagep[1]->addTextureStats(1024.f*1024.f);
}
-LLDrawPool *LLDrawPoolWater::instancePool()
+void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId)
{
- LL_ERRS() << "Should never be calling instancePool on a water pool!" << LL_ENDL;
- return NULL;
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId);
+ mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
}
-
-void LLDrawPoolWater::prerender()
+void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId)
{
- mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId());
+ mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()));
+ mWaterNormp[0]->addTextureStats(1024.f*1024.f);
+ mWaterNormp[1]->addTextureStats(1024.f*1024.f);
+}
- // got rid of modulation by light color since it got a little too
- // green at sunset and sl-57047 (underwater turns black at 8:00)
- sWaterFogColor = LLWaterParamManager::instance().getFogColor();
- sWaterFogColor.mV[3] = 0;
+//static
+void LLDrawPoolWater::restoreGL()
+{
+ /*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ if (pwater)
+ {
+ setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID());
+ setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId());
+ setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID());
+ }*/
+}
+void LLDrawPoolWater::prerender()
+{
+ mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
S32 LLDrawPoolWater::getNumPasses()
@@ -169,7 +163,7 @@ void LLDrawPoolWater::render(S32 pass)
std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
// See if we are rendering water as opaque or not
- if (!gSavedSettings.getBOOL("RenderTransparentWater"))
+ if (!LLPipeline::sRenderTransparentWater)
{
// render water for low end hardware
renderOpaqueLegacyWater();
@@ -178,7 +172,7 @@ void LLDrawPoolWater::render(S32 pass)
LLGLEnable blend(GL_BLEND);
- if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
+ if ((mShaderLevel > 0) && !sSkipScreenCopy)
{
shade();
return;
@@ -203,10 +197,13 @@ void LLDrawPoolWater::render(S32 pass)
LLGLDisable cullFace(GL_CULL_FACE);
// Set up second pass first
- mWaterImagep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->bind(mWaterImagep) ;
+ gGL.getTexUnit(1)->bind(mWaterImagep[0]) ;
+
+ gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->bind(mWaterImagep[1]) ;
LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
F32 up_dot = camera_up * LLVector3::z_axis;
@@ -263,6 +260,14 @@ void LLDrawPoolWater::render(S32 pass)
gGL.getTexUnit(1)->activate();
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->disable();
+
+ glDisable(GL_TEXTURE_GEN_S); //texture unit 1
+ glDisable(GL_TEXTURE_GEN_T); //texture unit 1
+
+ gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->disable();
+
glDisable(GL_TEXTURE_GEN_S); //texture unit 1
glDisable(GL_TEXTURE_GEN_T); //texture unit 1
@@ -362,8 +367,6 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
gPipeline.disableLights();
- mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
-
// Activate the texture binding and bind one
// texture since all images will have the same texture
gGL.getTexUnit(0)->activate();
@@ -461,97 +464,39 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
LLGLSNoFog noFog;
- gGL.getTexUnit(0)->bind(mHBTex[dr]);
+ gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex());
LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
face->renderIndexed();
}
-void LLDrawPoolWater::shade()
+void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
{
- if (!deferred_render)
- {
- gGL.setColorMask(true, true);
- }
-
- LLVOSky *voskyp = gSky.mVOSkyp;
+ F32 water_height = LLEnvironment::instance().getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ F32 eyedepth = camera_height - water_height;
+ bool underwater = eyedepth <= 0.0f;
- if(voskyp == NULL)
- {
- return;
- }
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
- LLGLDisable blend(GL_BLEND);
+ shader->bind();
- LLColor3 light_diffuse(0,0,0);
- F32 light_exp = 0.0f;
- LLVector3 light_dir;
- LLColor3 light_color;
-
- if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
- {
- light_dir = gSky.getSunDirection();
- light_dir.normVec();
- light_color = gSky.getSunDiffuseColor();
- if(gSky.mVOSkyp) {
- light_diffuse = gSky.mVOSkyp->getSun().getColorCached();
- light_diffuse.normVec();
- }
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
- light_diffuse *= light_exp + 0.25f;
- }
- else
- {
- light_dir = gSky.getMoonDirection();
- light_dir.normVec();
- light_color = gSky.getMoonDiffuseColor();
- light_diffuse = gSky.mVOSkyp->getMoon().getColorCached();
- light_diffuse.normVec();
- light_diffuse *= 0.5f;
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
- }
-
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= 256.f;
- light_exp = light_exp > 32.f ? light_exp : 32.f;
-
- LLGLSLShader* shader;
-
- F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
-
- if (eyedepth < 0.f && LLPipeline::sWaterReflections)
- {
+// bind textures for water rendering
if (deferred_render)
{
- shader = &gDeferredUnderWaterProgram;
- }
- else
- {
- shader = &gUnderWaterProgram;
- }
- }
- else if (deferred_render)
- {
- shader = &gDeferredWaterProgram;
- }
- else
- {
- shader = &gWaterProgram;
+ if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
+ {
+ glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
+ shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
+ }
}
- if (deferred_render)
- {
- gPipeline.bindDeferredShader(*shader);
- }
- else
- {
- shader->bind();
- }
+ LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor());
+ shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
- sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
+ sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
@@ -563,62 +508,65 @@ void LLDrawPoolWater::shade()
}
//bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
-
- LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- // change mWaterNormp if needed
- if (mWaterNormp->getID() != param_mgr->getNormalMapID())
- {
- mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
- }
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
- mWaterNormp->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
- if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- {
- mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
- }
+ F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
-
- if (screentex > -1)
- {
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,
- param_mgr->getFogDensity());
- gPipeline.mWaterDis.bindTexture(0, screentex);
- }
-
- stop_glerror();
-
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
-
- if (mVertexShaderLevel == 1)
- {
- sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
- }
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_b);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ }
+
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
F32 screenRes[] =
{
1.f/gGLViewport[2],
1.f/gGLViewport[3]
};
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- stop_glerror();
-
+
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
stop_glerror();
-
- light_dir.normVec();
- sLightDir = light_dir;
-
- light_diffuse *= 6.f;
+
+// set uniforms for water rendering
+ 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)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
+
+ if (mShaderLevel == 1)
+ {
+ //F32 fog_density_slider_value = param_mgr->mDensitySliderValue;
+ //sWaterFogColor.mV[3] = fog_density_slider_value;
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
+
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
@@ -626,76 +574,100 @@ void LLDrawPoolWater::shade()
shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ {
+ static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} };
+
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
+ }
+ else
+ {
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ }
shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier());
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
- F32 sunAngle = llmax(0.f, light_dir.mV[2]);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
F32 scaledAngle = 1.f - sunAngle;
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
+ 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(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLColor4 water_color;
- LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
- F32 up_dot = camera_up * LLVector3::z_axis;
if (LLViewerCamera::getInstance()->cameraUnderWater())
{
- water_color.setVec(1.f, 1.f, 1.f, 0.4f);
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
}
else
{
- water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
}
- if (water_color.mV[3] > 0.9f)
- {
- water_color.mV[3] = 0.9f;
- }
-
- {
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+ {
LLGLDisable cullface(GL_CULL_FACE);
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (voskyp->isReflFace(face))
- {
- continue;
- }
+ if (edge)
+ {
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+ {
+ LLFace *face = *iter;
+ if (face)
+ {
+ LLVOWater* water = (LLVOWater*) face->getViewerObject();
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+ if (water)
+ {
+ bool edge_patch = water->getIsEdgePatch();
+ if (edge_patch)
+ {
+ //sNeedsReflectionUpdate = TRUE;
+ face->renderIndexed();
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
+ {
+ LLFace *face = *iter;
+ if (face)
+ {
+ LLVOWater* water = (LLVOWater*) face->getViewerObject();
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+ if (water)
+ {
+ bool edge_patch = water->getIsEdgePatch();
+ if (!edge_patch)
+ {
+ sNeedsReflectionUpdate = TRUE;
+ sNeedsDistortionUpdate = TRUE;
+ face->renderIndexed();
+ }
+ }
+ }
+ }
+ }
+ }
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- sNeedsReflectionUpdate = TRUE;
-
- if (water->getUseTexture() || !water->getIsEdgePatch())
- {
- sNeedsDistortionUpdate = TRUE;
- face->renderIndexed();
- }
- else if (gGLManager.mHasDepthClamp || deferred_render)
- {
- face->renderIndexed();
- }
- else
- {
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
- face->renderIndexed();
- }
- }
- }
-
shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
shader->disableTexture(LLShaderMgr::BUMP_MAP);
@@ -703,14 +675,117 @@ void LLDrawPoolWater::shade()
shader->disableTexture(LLShaderMgr::WATER_REFTEX);
shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
- if (deferred_render)
+ shader->unbind();
+}
+
+void LLDrawPoolWater::shade()
+{
+ if (!deferred_render)
{
- gPipeline.unbindDeferredShader(*shader);
+ gGL.setColorMask(true, true);
}
- else
+
+ LLVOSky *voskyp = gSky.mVOSkyp;
+
+ if(voskyp == NULL)
+ {
+ return;
+ }
+
+ LLGLDisable blend(GL_BLEND);
+
+ LLColor3 light_diffuse(0,0,0);
+ F32 light_exp = 0.0f;
+ LLVector3 light_dir;
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ light_dir = environment.getLightDirection();
+ light_dir.normalize();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+
+ if (sun_up)
+ {
+ light_diffuse += voskyp->getSun().getColorCached();
+ }
+ // moonlight is several orders of magnitude less bright than sunlight,
+ // so only use this color when the moon alone is showing
+ else if (moon_up)
+ {
+ light_diffuse += psky->getMoonDiffuse();
+ }
+
+ light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f);
+
+ light_diffuse.normalize();
+ light_diffuse *= (light_exp + 0.25f);
+
+ light_exp *= light_exp;
+ light_exp *= light_exp;
+ light_exp *= light_exp;
+ light_exp *= light_exp;
+ light_exp *= 256.f;
+ light_exp = light_exp > 32.f ? light_exp : 32.f;
+
+ light_diffuse *= 6.f;
+
+ LLGLSLShader* shader = nullptr;
+ LLGLSLShader* edge_shader = nullptr;
+
+ F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight();
+
+ if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
- shader->unbind();
+ if (deferred_render)
+ {
+ shader = &gDeferredUnderWaterProgram;
+ }
+ else
+ {
+ shader = &gUnderWaterProgram;
+ }
}
+ else if (deferred_render)
+ {
+ shader = &gDeferredWaterProgram;
+ edge_shader = nullptr;
+ }
+ else
+ {
+ shader = &gWaterProgram;
+ edge_shader = &gWaterEdgeProgram;
+ }
+
+ if (mWaterNormp[0])
+ {
+ if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
+ }
+
+ if (mWaterNormp[1])
+ {
+ if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
+ }
+
+ shade2(false, shader, light_diffuse, light_dir, light_exp);
+ shade2(true, edge_shader ? edge_shader : shader, light_diffuse, light_dir, light_exp);
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index aeeba179d6..a5d163e0d7 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -33,22 +33,20 @@
class LLFace;
class LLHeavenBody;
class LLWaterSurface;
+class LLGLSLShader;
class LLDrawPoolWater: public LLFacePool
{
protected:
- LLPointer<LLViewerTexture> mHBTex[2];
- LLPointer<LLViewerTexture> mWaterImagep;
- LLPointer<LLViewerTexture> mOpaqueWaterImagep;
- LLPointer<LLViewerTexture> mWaterNormp;
+ LLPointer<LLViewerTexture> mWaterImagep[2];
+ LLPointer<LLViewerTexture> mWaterNormp[2];
+
+ LLPointer<LLViewerTexture> mOpaqueWaterImagep;
public:
static BOOL sSkipScreenCopy;
static BOOL sNeedsReflectionUpdate;
static BOOL sNeedsDistortionUpdate;
- static LLVector3 sLightDir;
-
- static LLColor4 sWaterFogColor;
static F32 sWaterFogEnd;
enum
@@ -63,7 +61,6 @@ public:
LLDrawPoolWater();
/*virtual*/ ~LLDrawPoolWater();
- /*virtual*/ LLDrawPool *instancePool();
static void restoreGL();
/*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
@@ -82,6 +79,11 @@ public:
void renderReflection(LLFace* face);
void shade();
+ void shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp);
+
+ void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId);
+ void setOpaqueTexture(const LLUUID& opaqueTextureId);
+ void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId);
protected:
void renderOpaqueLegacyWater();
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 309f535c39..0c3d8f3098 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -29,66 +29,39 @@
#include "lldrawpoolwlsky.h"
#include "llerror.h"
-#include "llgl.h"
-#include "pipeline.h"
-#include "llviewercamera.h"
+#include "llface.h"
#include "llimage.h"
-#include "llwlparammanager.h"
-#include "llviewershadermgr.h"
+#include "llrender.h"
+#include "llatmosphere.h"
+#include "llenvironment.h"
#include "llglslshader.h"
+#include "llgl.h"
+
+#include "llviewerregion.h"
+#include "llviewershadermgr.h"
+#include "llviewercamera.h"
+#include "pipeline.h"
#include "llsky.h"
#include "llvowlsky.h"
-#include "llviewerregion.h"
-#include "llface.h"
-#include "llrender.h"
-
-LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
+#include "llsettingsvo.h"
-LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
+static LLStaticHashedString sCamPosLocal("camPosLocal");
+static LLStaticHashedString sCustomAlpha("custom_alpha");
static LLGLSLShader* cloud_shader = NULL;
-static LLGLSLShader* sky_shader = NULL;
+static LLGLSLShader* sky_shader = NULL;
+static LLGLSLShader* sun_shader = NULL;
+static LLGLSLShader* moon_shader = NULL;
+static float sStarTime;
LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
LLDrawPool(POOL_WL_SKY)
{
- const std::string cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga"));
- LL_INFOS() << "loading WindLight cloud noise from " << cloudNoiseFilename << LL_ENDL;
-
- LLPointer<LLImageFormatted> cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename));
-
- if(cloudNoiseFile.isNull()) {
- LL_ERRS() << "Error: Failed to load cloud noise image " << cloudNoiseFilename << LL_ENDL;
- }
-
- if(cloudNoiseFile->load(cloudNoiseFilename))
- {
- sCloudNoiseRawImage = new LLImageRaw();
-
- if(cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f))
- {
- //debug use
- LL_DEBUGS() << "cloud noise raw image width: " << sCloudNoiseRawImage->getWidth() << " : height: " << sCloudNoiseRawImage->getHeight() << " : components: " <<
- (S32)sCloudNoiseRawImage->getComponents() << " : data size: " << sCloudNoiseRawImage->getDataSize() << LL_ENDL ;
- llassert_always(sCloudNoiseRawImage->getData()) ;
-
- sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
- }
- else
- {
- sCloudNoiseRawImage = NULL ;
- }
- }
-
- LLWLParamManager::getInstance()->propagateParameters();
}
LLDrawPoolWLSky::~LLDrawPoolWLSky()
{
- //LL_INFOS() << "destructing wlsky draw pool." << LL_ENDL;
- sCloudNoiseTexture = NULL;
- sCloudNoiseRawImage = NULL;
}
LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
@@ -107,39 +80,70 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass )
LLPipeline::sUnderWaterRender ?
&gObjectFullbrightNoColorWaterProgram :
&gWLCloudProgram;
+
+ sun_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gWLSunProgram;
+
+ moon_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gWLMoonProgram;
}
void LLDrawPoolWLSky::endRenderPass( S32 pass )
{
+ sky_shader = nullptr;
+ cloud_shader = nullptr;
+ sun_shader = nullptr;
+ moon_shader = nullptr;
}
void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
{
sky_shader = &gDeferredWLSkyProgram;
cloud_shader = &gDeferredWLCloudProgram;
+
+ sun_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gDeferredWLSunProgram;
+
+ moon_shader =
+ LLPipeline::sUnderWaterRender ?
+ &gObjectFullbrightNoColorWaterProgram :
+ &gDeferredWLMoonProgram;
}
void LLDrawPoolWLSky::endDeferredPass(S32 pass)
{
-
+ sky_shader = nullptr;
+ cloud_shader = nullptr;
+ sun_shader = nullptr;
+ moon_shader = nullptr;
}
-void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const
+void LLDrawPoolWLSky::renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
{
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ gSky.mVOWLSkyp->drawFsSky();
+}
- llassert_always(NULL != shader);
+void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
+{
+ llassert_always(NULL != shader);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
//chop off translation
- if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f)
+ if (LLPipeline::sReflectionRender && camPosLocal.mV[2] > 256.f)
{
- gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], 256.f-camPosLocal.mV[2]*0.5f);
}
else
{
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
}
@@ -151,64 +155,122 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons
gGL.translatef(0.f,-camHeightLocal, 0.f);
- // Draw WL Sky
- static LLStaticHashedString sCamPosLocal("camPosLocal");
+ // Draw WL Sky
shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
- gSky.mVOWLSkyp->drawDome();
+ gSky.mVOWLSkyp->drawDome();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
}
-void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
{
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
{
- LLGLDisable blend(GL_BLEND);
+ LLGLSPipelineDepthTestSkyBox sky(true, true);
- sky_shader->bind();
+ sky_shader->bind();
- /// Render the skydome
- renderDome(camHeightLocal, sky_shader);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLViewerTexture* rainbow_tex = gSky.mVOSkyp->getRainbowTex();
+ LLViewerTexture* halo_tex = gSky.mVOSkyp->getHaloTex();
+
+ sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex);
+ sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex);
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(sky_shader);
+
+ F32 moisture_level = (float)psky->getSkyMoistureLevel();
+ F32 droplet_radius = (float)psky->getSkyDropletRadius();
+ F32 ice_level = (float)psky->getSkyIceLevel();
+
+ // hobble halos and rainbows when there's no light source to generate them
+ if (!psky->getIsSunUp() && !psky->getIsMoonUp())
+ {
+ moisture_level = 0.0f;
+ ice_level = 0.0f;
+ }
+
+ sky_shader->uniform1f(LLShaderMgr::MOISTURE_LEVEL, moisture_level);
+ sky_shader->uniform1f(LLShaderMgr::DROPLET_RADIUS, droplet_radius);
+ sky_shader->uniform1f(LLShaderMgr::ICE_LEVEL, ice_level);
+
+ sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0);
+
+ /// Render the skydome
+ renderDome(origin, camHeightLocal, sky_shader);
sky_shader->unbind();
- }
+ }
+}
+
+void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const
+{
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ {
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ LLGLSPipelineDepthTestSkyBox sky(true, false);
+ sky_shader->bind();
+ sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
+ sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+ renderDome(origin, camHeightLocal, sky_shader);
+ sky_shader->unbind();
+ }
}
-void LLDrawPoolWLSky::renderStars(void) const
+void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
{
- LLGLSPipelineSkyBox gls_sky;
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ LLGLSPipelineBlendSkyBox gls_skybox(true, false);
// *NOTE: have to have bound the cloud noise texture already since register
// combiners blending below requires something to be bound
// and we might as well only bind once.
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gPipeline.disableLights();
-
// *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
// clamping and allow the star_alpha param to brighten the stars.
- bool error;
LLColor4 star_alpha(LLColor4::black);
- star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f;
- // If start_brightness is not set, exit
- if( error )
+ star_alpha.mV[3] = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 512.f;
+
+ // If star brightness is not set, exit
+ if( star_alpha.mV[3] < 0.001 )
{
- LL_WARNS() << "star_brightness missing in mCurParams" << LL_ENDL;
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
return;
}
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
+ LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex();
+ LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ gGL.getTexUnit(0)->bind(tex_a);
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_b);
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_a);
+ }
gGL.pushMatrix();
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
if (LLGLSLShader::sNoFixedFunction)
{
gCustomAlphaProgram.bind();
- static LLStaticHashedString sCustomAlpha("custom_alpha");
gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
}
else
@@ -220,6 +282,8 @@ void LLDrawPoolWLSky::renderStars(void) const
gSky.mVOWLSkyp->drawStars();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
gGL.popMatrix();
if (LLGLSLShader::sNoFixedFunction)
@@ -233,123 +297,299 @@ void LLDrawPoolWLSky::renderStars(void) const
}
}
-void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
+void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
- {
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
+ LLGLSPipelineBlendSkyBox gls_sky(true, false);
- cloud_shader->bind();
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- /// Render the skydome
- renderDome(camHeightLocal, cloud_shader);
+ F32 star_alpha = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 500.0f;
- cloud_shader->unbind();
+ // If start_brightness is not set, exit
+ if(star_alpha < 0.001f)
+ {
+ LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
+ return;
}
-}
-void LLDrawPoolWLSky::renderHeavenlyBodies()
-{
- LLGLSPipelineSkyBox gls_skybox;
- LLGLEnable blend_on(GL_BLEND);
- gPipeline.disableLights();
+ gDeferredStarProgram.bind();
-#if 0 // when we want to re-add a texture sun disc, here's where to do it.
- LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
- if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
- {
- LLViewerTexture * tex = face->getTexture();
- gGL.getTexUnit(0)->bind(tex);
- LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
- LLFacePool::LLOverrideFaceColor color_override(this, color);
- face->renderIndexed();
- }
-#endif
+ LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex();
+ LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext();
+
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ gGL.getTexUnit(0)->bind(tex_a);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_b);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(0)->bind(tex_a);
+ gGL.getTexUnit(1)->bind(tex_b);
+ }
+
+ gGL.pushMatrix();
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+ gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ if (LLPipeline::sReflectionRender)
+ {
+ star_alpha = 1.0f;
+ }
+ gDeferredStarProgram.uniform1f(sCustomAlpha, star_alpha);
- LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
+ sStarTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
- if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
+ gDeferredStarProgram.uniform1f(LLShaderMgr::WATER_TIME, sStarTime);
+
+ gSky.mVOWLSkyp->drawStars();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gDeferredStarProgram.unbind();
+
+ gGL.popMatrix();
+}
+
+void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
+{
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
{
- // *NOTE: even though we already bound this texture above for the
- // stars register combiners, we bind again here for defensive reasons,
- // since LLImageGL::bind detects that it's a noop, and optimizes it out.
- gGL.getTexUnit(0)->bind(face->getTexture());
- LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
- F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
- if (a > 0.f)
- {
- a = a*a*4.f;
- }
-
- color.mV[3] = llclamp(a, 0.f, 1.f);
-
- if (gPipeline.canUseVertexShaders())
- {
- gHighlightProgram.bind();
- }
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLFacePool::LLOverrideFaceColor color_override(this, color);
+ LLGLSPipelineBlendSkyBox pipeline(true, true);
- face->renderIndexed();
+ cloudshader->bind();
+
+ LLPointer<LLViewerTexture> cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
+ LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+ F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
+
+ // if we even have sun disc textures to work with...
+ if (cloud_noise || cloud_noise_next)
+ {
+ if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+ {
+ // Bind current and next sun textures
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next && !cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next != cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+ cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
+
+ /// Render the skydome
+ renderDome(camPosLocal, camHeightLocal, cloudshader);
+
+ cloudshader->unbind();
- if (gPipeline.canUseVertexShaders())
- {
- gHighlightProgram.unbind();
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
}
}
-void LLDrawPoolWLSky::renderDeferred(S32 pass)
+void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
{
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
{
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
+ LLGLSPipelineBlendSkyBox pipeline(true, true);
+
+ cloudshader->bind();
+
+ LLPointer<LLViewerTexture> cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
+ LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
+ F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
+
+ // if we even have sun disc textures to work with...
+ if (cloud_noise || cloud_noise_next)
+ {
+ if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
+ {
+ // Bind current and next sun textures
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next && !cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (cloud_noise_next != cloud_noise)
+ {
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
+ cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
+ cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
+
+ ((LLSettingsVOSky*)psky.get())->updateShader(cloudshader);
- LLGLSNoFog disableFog;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable clip(GL_CLIP_PLANE0);
+ /// Render the skydome
+ renderDome(camPosLocal, camHeightLocal, cloudshader);
- gGL.setColorMask(true, false);
+ cloudshader->unbind();
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+}
- renderSkyHaze(camHeightLocal);
+void LLDrawPoolWLSky::renderHeavenlyBodies()
+{
+ LLGLSPipelineBlendSkyBox gls_skybox(true, false);
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
gGL.pushMatrix();
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
- gDeferredStarProgram.bind();
- // *NOTE: have to bind a texture here since register combiners blending in
- // renderStars() requires something to be bound and we might as well only
- // bind the moon's texture once.
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
+ F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
+ bool can_use_vertex_shaders = gPipeline.canUseVertexShaders();
+ bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders();
- renderHeavenlyBodies();
- renderStars();
-
- gDeferredStarProgram.unbind();
-
- gGL.popMatrix();
+ if (gSky.mVOSkyp->getSun().getDraw() && face && face->getGeomCount())
+ {
+ LLPointer<LLViewerTexture> tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ LLPointer<LLViewerTexture> tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // if we even have sun disc textures to work with...
+ if (tex_a || tex_b)
+ {
+ // if and only if we have a texture defined, render the sun disc
+ if (can_use_vertex_shaders && can_use_windlight_shaders)
+ {
+ sun_shader->bind();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ blend_factor = 0;
+ }
+ else if (tex_b != tex_a)
+ {
+ sun_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ sun_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ }
+
+ LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
+
+ sun_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
+ sun_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ sun_shader->unbind();
+ }
+ }
+ }
- renderSkyClouds(camHeightLocal);
+ face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
- gGL.setColorMask(true, true);
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (gSky.mVOSkyp->getMoon().getDraw() && face && face->getTexture(LLRender::DIFFUSE_MAP) && face->getGeomCount() && moon_shader)
+ {
+ LLViewerTexture* tex_a = face->getTexture(LLRender::DIFFUSE_MAP);
+ LLViewerTexture* tex_b = face->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
+ LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
+
+ if (can_use_vertex_shaders && can_use_windlight_shaders && (tex_a || tex_b))
+ {
+ moon_shader->bind();
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ // Bind current and next sun textures
+ moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ //blend_factor = 0;
+ }
+ else if (tex_b && !tex_a)
+ {
+ moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ //blend_factor = 0;
+ }
+ else if (tex_b != tex_a)
+ {
+ moon_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, tex_a, LLTexUnit::TT_TEXTURE);
+ //moon_shader->bindTexture(LLShaderMgr::ALTERNATE_DIFFUSE_MAP, tex_b, LLTexUnit::TT_TEXTURE);
+ }
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ 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->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
+
+ face->renderIndexed();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+
+ moon_shader->unbind();
+ }
+ }
+
+ gGL.popMatrix();
}
-void LLDrawPoolWLSky::render(S32 pass)
+void LLDrawPoolWLSky::renderDeferred(S32 pass)
{
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
{
@@ -357,34 +597,37 @@ void LLDrawPoolWLSky::render(S32 pass)
}
LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
-
- LLGLSNoFog disableFog;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable clip(GL_CLIP_PLANE0);
-
- LLGLSquashToFarClip far_clip(glh_get_current_projection());
-
- renderSkyHaze(camHeightLocal);
-
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.pushMatrix();
-
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
- // *NOTE: have to bind a texture here since register combiners blending in
- // renderStars() requires something to be bound and we might as well only
- // bind the moon's texture once.
- gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
+ gGL.setColorMask(true, false);
- renderHeavenlyBodies();
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
- renderStars();
-
+ if (gPipeline.canUseWindLightShaders())
+ {
+ renderSkyHazeDeferred(origin, camHeightLocal);
+ renderStarsDeferred(origin);
+ renderHeavenlyBodies();
+ renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
+ }
+ gGL.setColorMask(true, true);
+}
- gGL.popMatrix();
+void LLDrawPoolWLSky::render(S32 pass)
+{
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ {
+ return;
+ }
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- renderSkyClouds(camHeightLocal);
+ const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
+ LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
+
+ renderSkyHaze(origin, camHeightLocal);
+ renderStars(origin);
+ renderHeavenlyBodies();
+ renderSkyClouds(origin, camHeightLocal, cloud_shader);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -394,11 +637,6 @@ void LLDrawPoolWLSky::prerender()
//LL_INFOS() << "wlsky prerendering pass." << LL_ENDL;
}
-LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool()
-{
- return new LLDrawPoolWLSky();
-}
-
LLViewerTexture* LLDrawPoolWLSky::getTexture()
{
return NULL;
@@ -411,15 +649,9 @@ void LLDrawPoolWLSky::resetDrawOrders()
//static
void LLDrawPoolWLSky::cleanupGL()
{
- sCloudNoiseTexture = NULL;
}
//static
void LLDrawPoolWLSky::restoreGL()
{
- if(sCloudNoiseRawImage.notNull())
- {
- sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
- }
}
-
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index cd15c991ee..324886ed42 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -38,7 +38,8 @@ public:
LLVertexBuffer::MAP_TEXCOORD0;
static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
-
+ static const U32 ADV_ATMO_SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX
+ | LLVertexBuffer::MAP_TEXCOORD0;
LLDrawPoolWLSky(void);
/*virtual*/ ~LLDrawPoolWLSky();
@@ -57,12 +58,10 @@ public:
/*virtual*/ void prerender();
/*virtual*/ U32 getVertexDataMask() { return SKY_VERTEX_DATA_MASK; }
/*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
- /*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
+ /*virtual*/ S32 getShaderLevel() const { return mShaderLevel; }
//static LLDrawPool* createPool(const U32 type, LLViewerTexture *tex0 = NULL);
- // Create an empty new instance of the pool.
- /*virtual*/ LLDrawPoolWLSky *instancePool(); ///< covariant override
/*virtual*/ LLViewerTexture* getTexture();
/*virtual*/ BOOL isFacePool() { return FALSE; }
/*virtual*/ void resetDrawOrders();
@@ -70,15 +69,18 @@ public:
static void cleanupGL();
static void restoreGL();
private:
- void renderDome(F32 camHeightLocal, LLGLSLShader * shader) const;
- void renderSkyHaze(F32 camHeightLocal) const;
- void renderStars(void) const;
- void renderSkyClouds(F32 camHeightLocal) const;
- void renderHeavenlyBodies();
+ void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
+ void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
-private:
- static LLPointer<LLViewerTexture> sCloudNoiseTexture;
- static LLPointer<LLImageRaw> sCloudNoiseRawImage;
+ void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+ void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+ void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
+ void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
+
+ void renderStarsDeferred(const LLVector3& camPosLocal) const;
+ void renderStars(const LLVector3& camPosLocal) const;
+ void renderHeavenlyBodies();
};
#endif // LL_DRAWPOOLWLSKY_H
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 8ef0dd2865..8b8273d183 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -56,13 +56,6 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon
{
llassert((1 <= components) && (components <= 4));
- if(gGLManager.mDebugGPU)
- {
- if(components == 3)
- {
- mComponents = 4 ; //convert to 32bits.
- }
- }
generateGLTexture();
llassert( 0 <= order && order < ORDER_COUNT );
@@ -125,11 +118,11 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
- //only images up to 1024*1024 are supported
- llassert(mFullHeight <= 512);
- llassert(mFullWidth <= 512);
+ gPipeline.allocatePhysicsBuffer();
+ llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
+ llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
- if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
+ if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -211,16 +204,17 @@ void LLViewerDynamicTexture::postRender(BOOL success)
BOOL LLViewerDynamicTexture::updateAllInstances()
{
sNumRenders = 0;
- if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)
+ if (gGLManager.mIsDisabled)
{
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsATI;
if (use_fbo)
{
- gPipeline.mWaterDis.bindTarget();
+ gPipeline.mBake.bindTarget();
+ gPipeline.mBake.clear();
}
LLGLSLShader::bindNoShader();
@@ -240,6 +234,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
gDepthDirty = TRUE;
gGL.color4f(1,1,1,1);
+ dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr);
dynamicTexture->preRender(); // Must be called outside of startRender()
result = FALSE;
if (dynamicTexture->render())
@@ -250,7 +245,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
}
gGL.flush();
LLVertexBuffer::unbind();
-
+ dynamicTexture->setBoundTarget(nullptr);
dynamicTexture->postRender(result);
}
}
@@ -258,9 +253,11 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
if (use_fbo)
{
- gPipeline.mWaterDis.flush();
+ gPipeline.mBake.flush();
}
+ gGL.flush();
+
return ret;
}
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index f3f57c9a6b..4bd74a8425 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -88,6 +88,9 @@ public:
static BOOL updateAllInstances();
static void destroyGL() ;
static void restoreGL() ;
+
+ void setBoundTarget(LLRenderTarget* target) { mBoundTarget = target; }
+
protected:
void generateGLTexture();
void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE);
@@ -97,6 +100,8 @@ protected:
LLCoordGL mOrigin;
LL_ALIGN_16(LLCamera mCamera);
+ LLRenderTarget* mBoundTarget;
+
typedef std::set<LLViewerDynamicTexture*> instance_list_t;
static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
static S32 sNumRenders;
diff --git a/indra/newview/llenvadapters.cpp b/indra/newview/llenvadapters.cpp
new file mode 100644
index 0000000000..fdbcf68fa4
--- /dev/null
+++ b/indra/newview/llenvadapters.cpp
@@ -0,0 +1,67 @@
+/**
+ * @file llenvadapters.cpp
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llenvadapters.h"
+
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+//=========================================================================
+
+LLSkySettingsAdapter::LLSkySettingsAdapter():
+ mWLGamma(1.0f, LLSettingsSky::SETTING_GAMMA),
+
+ // Lighting
+ mLightnorm(LLColor4(0.f, 0.707f, -0.707f, 1.f), LLSettingsSky::SETTING_LIGHT_NORMAL),
+ mSunlight(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_SUNLIGHT_COLOR, "WLSunlight"),
+
+ mGlow(LLColor4(18.0f, 0.0f, -0.01f, 1.0f), LLSettingsSky::SETTING_GLOW),
+ // Clouds
+ mCloudColor(LLColor4(0.5f, 0.5f, 0.5f, 1.0f), LLSettingsSky::SETTING_CLOUD_COLOR, "WLCloudColor"),
+ mCloudMain(LLColor4(0.5f, 0.5f, 0.125f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY1),
+ mCloudCoverage(0.0f, LLSettingsSky::SETTING_CLOUD_SHADOW),
+ mCloudDetail(LLColor4(0.0f, 0.0f, 0.0f, 1.0f), LLSettingsSky::SETTING_CLOUD_POS_DENSITY2),
+ mCloudScale(0.42f, LLSettingsSky::SETTING_CLOUD_SCALE)
+{
+
+}
+
+LLWatterSettingsAdapter::LLWatterSettingsAdapter():
+ mFogColor(LLColor4((22.f / 255.f), (43.f / 255.f), (54.f / 255.f), (0.0f)), LLSettingsWater::SETTING_FOG_COLOR, "WaterFogColor"),
+ mFogDensity(4, LLSettingsWater::SETTING_FOG_DENSITY, 2),
+ mUnderWaterFogMod(0.25, LLSettingsWater::SETTING_FOG_MOD),
+ mNormalScale(LLVector3(2.f, 2.f, 2.f), LLSettingsWater::SETTING_NORMAL_SCALE),
+ mFresnelScale(0.5f, LLSettingsWater::SETTING_FRESNEL_SCALE),
+ mFresnelOffset(0.4f, LLSettingsWater::SETTING_FRESNEL_OFFSET),
+ mScaleAbove(0.025f, LLSettingsWater::SETTING_SCALE_ABOVE),
+ mScaleBelow(0.2f, LLSettingsWater::SETTING_SCALE_BELOW),
+ mBlurMultiplier(0.1f, LLSettingsWater::SETTING_BLUR_MULTIPILER),
+ mWave1Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE1_DIR),
+ mWave2Dir(LLVector2(0.5f, 0.5f), LLSettingsWater::SETTING_WAVE2_DIR)
+
+{
+
+}
diff --git a/indra/newview/llenvadapters.h b/indra/newview/llenvadapters.h
new file mode 100644
index 0000000000..bd58db0589
--- /dev/null
+++ b/indra/newview/llenvadapters.h
@@ -0,0 +1,459 @@
+/**
+ * @file llenvadapters.h
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_ENVADAPTERS_H
+#define LL_ENVADAPTERS_H
+
+#include "v3math.h"
+#include "v3color.h"
+#include "v4math.h"
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+
+class WLColorControl
+{
+public:
+ inline WLColorControl(LLColor4 color, const std::string& n, const std::string& slider_name = std::string()):
+ mColor(color),
+ mName(n),
+ mSliderName(slider_name),
+ mHasSliderName(false),
+ mIsSunOrAmbientColor(false),
+ mIsBlueHorizonOrDensity(false)
+ {
+ // if there's a slider name, say we have one
+ mHasSliderName = !mSliderName.empty();
+
+ // if it's the sun controller
+ mIsSunOrAmbientColor = (mSliderName == "WLSunlight" || mSliderName == "WLAmbient");
+ mIsBlueHorizonOrDensity = (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity");
+ }
+
+ inline void setColor4(const LLColor4 & val)
+ {
+ mColor = val;
+ }
+
+ inline void setColor3(const LLColor3 & val)
+ {
+ mColor = val;
+ }
+
+ inline LLColor4 getColor4() const
+ {
+ return mColor;
+ }
+
+ inline LLColor3 getColor3(void) const
+ {
+ return vec4to3(mColor);
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, mColor);
+ }
+
+ inline bool getHasSliderName() const
+ {
+ return mHasSliderName;
+ }
+
+ inline std::string getSliderName() const
+ {
+ return mSliderName;
+ }
+
+ inline bool getIsSunOrAmbientColor() const
+ {
+ return mIsSunOrAmbientColor;
+ }
+
+ inline bool getIsBlueHorizonOrDensity() const
+ {
+ return mIsBlueHorizonOrDensity;
+ }
+
+ inline F32 getRed() const
+ {
+ return mColor[0];
+ }
+
+ inline F32 getGreen() const
+ {
+ return mColor[1];
+ }
+
+ inline F32 getBlue() const
+ {
+ return mColor[2];
+ }
+
+ inline F32 getIntensity() const
+ {
+ return mColor[3];
+ }
+
+ inline void setRed(F32 red)
+ {
+ mColor[0] = red;
+ }
+
+ inline void setGreen(F32 green)
+ {
+ mColor[1] = green;
+ }
+
+ inline void setBlue(F32 blue)
+ {
+ mColor[2] = blue;
+ }
+
+ inline void setIntensity(F32 intensity)
+ {
+ mColor[3] = intensity;
+ }
+
+private:
+ LLColor4 mColor; /// [3] is intensity, not alpha
+ std::string mName; /// name to use to dereference params
+ std::string mSliderName; /// name of the slider in menu
+ bool mHasSliderName; /// only set slider name for true color types
+ bool mIsSunOrAmbientColor; /// flag for if it's the sun or ambient color controller
+ bool mIsBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller
+
+};
+
+// float slider control
+class WLFloatControl
+{
+public:
+ inline WLFloatControl(F32 val, const std::string& n, F32 m = 1.0f):
+ x(val),
+ mName(n),
+ mult(m)
+ {
+ }
+
+ inline WLFloatControl &operator = (F32 val)
+ {
+ x = val;
+ return *this;
+ }
+
+ inline operator F32 (void) const
+ {
+ return x;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, x);
+ }
+
+ inline F32 getMult() const
+ {
+ return mult;
+ }
+
+ inline void setValue(F32 val)
+ {
+ x = val;
+ }
+
+private:
+ F32 x;
+ std::string mName;
+ F32 mult;
+};
+
+class WLXFloatControl
+{
+public:
+ inline WLXFloatControl(F32 val, const std::string& n, F32 b):
+ mExp(val),
+ mBase(b),
+ mName(n)
+ {
+ }
+
+ inline WLXFloatControl & operator = (F32 val)
+ {
+ mExp = log(val) / log(mBase);
+
+ return *this;
+ }
+
+ inline operator F32 (void) const
+ {
+ return pow(mBase, mExp);
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, pow(mBase, mExp));
+ }
+
+ inline F32 getExp() const
+ {
+ return mExp;
+ }
+
+ inline void setExp(F32 val)
+ {
+ mExp = val;
+ }
+
+ inline F32 getBase() const
+ {
+ return mBase;
+ }
+
+ inline void setBase(F32 val)
+ {
+ mBase = val;
+ }
+
+private:
+ F32 mExp;
+ F32 mBase;
+ std::string mName;
+};
+
+class WLVect2Control
+{
+public:
+ inline WLVect2Control(LLVector2 val, const std::string& n):
+ mU(val.mV[0]),
+ mV(val.mV[1]),
+ mName(n)
+ {
+ }
+
+ inline WLVect2Control & operator = (const LLVector2 & val)
+ {
+ mU = val.mV[0];
+ mV = val.mV[1];
+
+ return *this;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, LLVector2(mU, mV));
+ }
+
+ inline F32 getU() const
+ {
+ return mU;
+ }
+
+ inline void setU(F32 val)
+ {
+ mU = val;
+ }
+
+ inline F32 getV() const
+ {
+ return mV;
+ }
+
+ inline void setV(F32 val)
+ {
+ mV = val;
+ }
+
+private:
+ F32 mU;
+ F32 mV;
+ std::string mName;
+};
+
+class WLVect3Control
+{
+public:
+ inline WLVect3Control(LLVector3 val, const std::string& n):
+ mX(val.mV[0]),
+ mY(val.mV[1]),
+ mZ(val.mV[2]),
+ mName(n)
+ {
+ }
+
+ inline WLVect3Control & operator = (const LLVector3 & val)
+ {
+ mX = val.mV[0];
+ mY = val.mV[1];
+ mZ = val.mV[2];
+
+ return *this;
+ }
+
+ inline void update(const LLSettingsBase::ptr_t &psetting) const
+ {
+ psetting->setValue(mName, LLVector3(mX, mY, mZ));
+ }
+
+ inline F32 getX() const
+ {
+ return mX;
+ }
+
+ inline void setX(F32 val)
+ {
+ mX = val;
+ }
+
+ inline F32 getY() const
+ {
+ return mY;
+ }
+
+ inline void setY(F32 val)
+ {
+ mY = val;
+ }
+
+ inline F32 getZ() const
+ {
+ return mZ;
+ }
+
+ inline void setZ(F32 val)
+ {
+ mZ = val;
+ }
+
+private:
+ F32 mX;
+ F32 mY;
+ F32 mZ;
+ std::string mName;
+};
+
+class LLDensityProfileSettingsAdapter
+{
+public:
+ LLDensityProfileSettingsAdapter(const std::string& config, int layerIndex = 0)
+ : mConfig(config)
+ , mLayerIndex(layerIndex)
+ , mLayerWidth(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH)
+ , mExpTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM)
+ , mExpScale(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR)
+ , mLinTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM)
+ , mConstantTerm(1.0f, LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM)
+ {}
+
+protected:
+ std::string mConfig;
+ int mLayerIndex;
+ WLFloatControl mLayerWidth; // 0.0 -> to top of atmosphere, however big that may be.
+ WLFloatControl mExpTerm;
+ WLFloatControl mExpScale;
+ WLFloatControl mLinTerm;
+ WLFloatControl mConstantTerm;
+};
+
+class LLRayleighDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLRayleighDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_RAYLEIGH_CONFIG, layerIndex)
+ {
+ }
+};
+
+class LLMieDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLMieDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_MIE_CONFIG, layerIndex)
+ , mAnisotropy(0.8f, LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR)
+ {
+ }
+
+protected:
+ WLFloatControl mAnisotropy;
+};
+
+class LLAbsorptionDensityProfileSettingsAdapter : public LLDensityProfileSettingsAdapter
+{
+public:
+ LLAbsorptionDensityProfileSettingsAdapter(int layerIndex = 0)
+ : LLDensityProfileSettingsAdapter(LLSettingsSky::SETTING_ABSORPTION_CONFIG, layerIndex)
+ {
+ }
+};
+
+//-------------------------------------------------------------------------
+class LLSkySettingsAdapter
+{
+public:
+ typedef std::shared_ptr<LLSkySettingsAdapter> ptr_t;
+
+ LLSkySettingsAdapter();
+
+ WLFloatControl mWLGamma;
+
+ /// Lighting
+ WLColorControl mLightnorm;
+ WLColorControl mSunlight;
+ WLColorControl mGlow;
+
+ /// Clouds
+ WLColorControl mCloudColor;
+ WLColorControl mCloudMain;
+ WLFloatControl mCloudCoverage;
+ WLColorControl mCloudDetail;
+ WLFloatControl mCloudScale;
+};
+
+class LLWatterSettingsAdapter
+{
+public:
+ typedef std::shared_ptr<LLWatterSettingsAdapter> ptr_t;
+
+ LLWatterSettingsAdapter();
+
+ WLColorControl mFogColor;
+ WLXFloatControl mFogDensity;
+ WLFloatControl mUnderWaterFogMod;
+
+ /// wavelet scales and directions
+ WLVect3Control mNormalScale;
+ WLVect2Control mWave1Dir;
+ WLVect2Control mWave2Dir;
+
+ // controls how water is reflected and refracted
+ WLFloatControl mFresnelScale;
+ WLFloatControl mFresnelOffset;
+ WLFloatControl mScaleAbove;
+ WLFloatControl mScaleBelow;
+ WLFloatControl mBlurMultiplier;
+
+};
+
+#endif // LL_ENVIRONMENT_H
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
new file mode 100644
index 0000000000..190051d763
--- /dev/null
+++ b/indra/newview/llenvironment.cpp
@@ -0,0 +1,3480 @@
+/**
+ * @file llenvmanager.cpp
+ * @brief Implementation of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llenvironment.h"
+
+#include <algorithm>
+
+#include "llagent.h"
+#include "llviewercontrol.h" // for gSavedSettings
+#include "llviewerregion.h"
+#include "llwlhandlers.h"
+#include "lltrans.h"
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "llviewercamera.h"
+#include "pipeline.h"
+#include "llsky.h"
+
+#include "llviewershadermgr.h"
+
+#include "llparcel.h"
+#include "llviewerparcelmgr.h"
+
+#include "llsdserialize.h"
+#include "lldiriterator.h"
+
+#include "llsettingsvo.h"
+#include "llnotificationsutil.h"
+
+#include "llregioninfomodel.h"
+
+#include <boost/make_shared.hpp>
+
+#include "llatmosphere.h"
+#include "llagent.h"
+#include "roles_constants.h"
+#include "llestateinfomodel.h"
+
+#include "lldispatcher.h"
+#include "llviewergenericmessage.h"
+#include "llexperiencelog.h"
+
+//=========================================================================
+namespace
+{
+ const std::string KEY_ENVIRONMENT("environment");
+ const std::string KEY_DAYASSET("day_asset");
+ const std::string KEY_DAYCYCLE("day_cycle");
+ const std::string KEY_DAYHASH("day_hash");
+ const std::string KEY_DAYLENGTH("day_length");
+ const std::string KEY_DAYNAME("day_name");
+ const std::string KEY_DAYNAMES("day_names");
+ const std::string KEY_DAYOFFSET("day_offset");
+ const std::string KEY_ENVVERSION("env_version");
+ const std::string KEY_ISDEFAULT("is_default");
+ const std::string KEY_PARCELID("parcel_id");
+ const std::string KEY_REGIONID("region_id");
+ const std::string KEY_TRACKALTS("track_altitudes");
+ const std::string KEY_FLAGS("flags");
+
+ const std::string MESSAGE_PUSHENVIRONMENT("PushExpEnvironment");
+
+ const std::string ACTION_CLEARENVIRONMENT("ClearEnvironment");
+ const std::string ACTION_PUSHFULLENVIRONMENT("PushFullEnvironment");
+ const std::string ACTION_PUSHPARTIALENVIRONMENT("PushPartialEnvironment");
+
+ const std::string KEY_ASSETID("asset_id");
+ const std::string KEY_TRANSITIONTIME("transition_time");
+ const std::string KEY_ACTION("action");
+ const std::string KEY_ACTIONDATA("action_data");
+ const std::string KEY_EXPERIENCEID("public_id");
+ const std::string KEY_OBJECTNAME("ObjectName"); // some of these do not conform to the '_' format.
+ const std::string KEY_PARCELNAME("ParcelName"); // But changing these would also alter the Experience Log requirements.
+ const std::string KEY_COUNT("Count");
+
+ const std::string LISTENER_NAME("LLEnvironmentSingleton");
+ const std::string PUMP_EXPERIENCE("experience_permission");
+
+ const std::string LOCAL_ENV_STORAGE_FILE("local_environment_data.bin");
+
+ //---------------------------------------------------------------------
+ LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick");
+ LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters");
+
+ LLSettingsBase::Seconds DEFAULT_UPDATE_THRESHOLD(10.0);
+ const LLSettingsBase::Seconds MINIMUM_SPANLENGTH(0.01f);
+
+ //---------------------------------------------------------------------
+ inline LLSettingsBase::TrackPosition get_wrapping_distance(LLSettingsBase::TrackPosition begin, LLSettingsBase::TrackPosition end)
+ {
+ if (begin < end)
+ {
+ return end - begin;
+ }
+ else if (begin > end)
+ {
+ return LLSettingsBase::TrackPosition(1.0) - (begin - end);
+ }
+
+ return 1.0f;
+ }
+
+ LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
+ {
+ if (collection.empty())
+ return collection.end();
+
+ LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key);
+
+ if (it == collection.end())
+ { // wrap around
+ it = collection.begin();
+ }
+
+ return it;
+ }
+
+ LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
+ {
+ if (collection.empty())
+ return collection.end();
+
+ LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key);
+
+ if (it == collection.end())
+ { // all keyframes are lower, take the last one.
+ --it; // we know the range is not empty
+ }
+ else if ((*it).first > key)
+ { // the keyframe we are interested in is smaller than the found.
+ if (it == collection.begin())
+ it = collection.end();
+ --it;
+ }
+
+ return it;
+ }
+
+ LLSettingsDay::TrackBound_t get_bounding_entries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
+ {
+ return LLSettingsDay::TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
+ }
+
+ // Find normalized track position of given time along full length of cycle
+ inline LLSettingsBase::TrackPosition convert_time_to_position(const LLSettingsBase::Seconds& time, const LLSettingsBase::Seconds& len)
+ {
+ LLSettingsBase::TrackPosition position = LLSettingsBase::TrackPosition(fmod((F64)time, (F64)len) / (F64)len);
+ return llclamp(position, 0.0f, 1.0f);
+ }
+
+ inline LLSettingsBase::BlendFactor convert_time_to_blend_factor(const LLSettingsBase::Seconds& time, const LLSettingsBase::Seconds& len, LLSettingsDay::CycleTrack_t &track)
+ {
+ LLSettingsBase::TrackPosition position = convert_time_to_position(time, len);
+ LLSettingsDay::TrackBound_t bounds(get_bounding_entries(track, position));
+
+ LLSettingsBase::TrackPosition spanlength(get_wrapping_distance((*bounds.first).first, (*bounds.second).first));
+ if (position < (*bounds.first).first)
+ position += 1.0;
+
+ LLSettingsBase::TrackPosition start = position - (*bounds.first).first;
+
+ return static_cast<LLSettingsBase::BlendFactor>(start / spanlength);
+ }
+
+ //---------------------------------------------------------------------
+ class LLTrackBlenderLoopingTime : public LLSettingsBlenderTimeDelta
+ {
+ public:
+ LLTrackBlenderLoopingTime(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno,
+ LLSettingsBase::Seconds cyclelength, LLSettingsBase::Seconds cycleoffset, LLSettingsBase::Seconds updateThreshold) :
+ LLSettingsBlenderTimeDelta(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t(), LLSettingsBase::Seconds(1.0)),
+ mDay(day),
+ mTrackNo(0),
+ mCycleLength(cyclelength),
+ mCycleOffset(cycleoffset)
+ {
+ // must happen prior to getBoundingEntries call...
+ mTrackNo = selectTrackNumber(trackno);
+
+ LLSettingsBase::Seconds now(getAdjustedNow());
+ LLSettingsDay::TrackBound_t initial = getBoundingEntries(now);
+
+ mInitial = (*initial.first).second;
+ mFinal = (*initial.second).second;
+ mBlendSpan = getSpanTime(initial);
+
+ initializeTarget(now);
+ setOnFinished([this](const LLSettingsBlender::ptr_t &){ onFinishedSpan(); });
+ }
+
+ void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition&) override
+ {
+ S32 use_trackno = selectTrackNumber(trackno);
+
+ if (use_trackno == mTrackNo)
+ { // results in no change
+ return;
+ }
+
+ LLSettingsBase::ptr_t pstartsetting = mTarget->buildDerivedClone();
+ mTrackNo = use_trackno;
+
+ LLSettingsBase::Seconds now = getAdjustedNow() + LLEnvironment::TRANSITION_ALTITUDE;
+ LLSettingsDay::TrackBound_t bounds = getBoundingEntries(now);
+
+ LLSettingsBase::ptr_t pendsetting = (*bounds.first).second->buildDerivedClone();
+ LLSettingsBase::TrackPosition targetpos = convert_time_to_position(now, mCycleLength) - (*bounds.first).first;
+ LLSettingsBase::TrackPosition targetspan = get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+
+ LLSettingsBase::BlendFactor blendf = calculateBlend(targetpos, targetspan);
+ pendsetting->blend((*bounds.second).second, blendf);
+
+ reset(pstartsetting, pendsetting, LLEnvironment::TRANSITION_ALTITUDE);
+ }
+
+ protected:
+ S32 selectTrackNumber(S32 trackno)
+ {
+ if (trackno == 0)
+ { // We are dealing with the water track. There is only ever one.
+ return trackno;
+ }
+
+ for (S32 test = trackno; test != 0; --test)
+ { // Find the track below the requested one with data.
+ LLSettingsDay::CycleTrack_t &track = mDay->getCycleTrack(test);
+
+ if (!track.empty())
+ return test;
+ }
+
+ return 1;
+ }
+
+ LLSettingsDay::TrackBound_t getBoundingEntries(LLSettingsBase::Seconds time)
+ {
+ LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo);
+ LLSettingsBase::TrackPosition position = convert_time_to_position(time, mCycleLength);
+ LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position);
+ return bounds;
+ }
+
+ void initializeTarget(LLSettingsBase::Seconds time)
+ {
+ LLSettingsBase::BlendFactor blendf(convert_time_to_blend_factor(time, mCycleLength, mDay->getCycleTrack(mTrackNo)));
+
+ blendf = llclamp(blendf, 0.0, 0.999);
+ setTimeSpent(LLSettingsBase::Seconds(blendf * mBlendSpan));
+
+ setBlendFactor(blendf);
+ }
+
+ LLSettingsBase::Seconds getAdjustedNow() const
+ {
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+
+ return (now + mCycleOffset);
+ }
+
+ LLSettingsBase::Seconds getSpanTime(const LLSettingsDay::TrackBound_t &bounds) const
+ {
+ LLSettingsBase::Seconds span = mCycleLength * get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+ if (span < MINIMUM_SPANLENGTH) // for very short spans set a minimum length.
+ span = MINIMUM_SPANLENGTH;
+ return span;
+ }
+
+ private:
+ LLSettingsDay::ptr_t mDay;
+ S32 mTrackNo;
+ LLSettingsBase::Seconds mCycleLength;
+ LLSettingsBase::Seconds mCycleOffset;
+
+ void onFinishedSpan()
+ {
+ LLSettingsBase::Seconds adjusted_now = getAdjustedNow();
+ LLSettingsDay::TrackBound_t next = getBoundingEntries(adjusted_now);
+ LLSettingsBase::Seconds nextspan = getSpanTime(next);
+
+ reset((*next.first).second, (*next.second).second, nextspan);
+
+ // Recalculate (reinitialize) position. Because:
+ // - 'delta' from applyTimeDelta accumulates errors (probably should be fixed/changed to absolute time)
+ // - freezes and lag can result in reset being called too late, so we need to add missed time
+ // - occasional time corrections can happen
+ // - some transition switches can happen outside applyTimeDelta thus causing 'desync' from 'delta' (can be fixed by getting rid of delta)
+ initializeTarget(adjusted_now);
+ }
+ };
+
+ class LLEnvironmentPushDispatchHandler : public LLDispatchHandler
+ {
+ public:
+ virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
+ {
+ 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() << "LLEnvironmentPushDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ }
+ }
+
+ message[KEY_EXPERIENCEID] = invoice;
+ // Object Name
+ if (it != strings.end())
+ {
+ message[KEY_OBJECTNAME] = *it++;
+ }
+
+ // parcel Name
+ if (it != strings.end())
+ {
+ message[KEY_PARCELNAME] = *it++;
+ }
+ message[KEY_COUNT] = 1;
+
+ LLEnvironment::instance().handleEnvironmentPush(message);
+ return true;
+ }
+ };
+
+ LLEnvironmentPushDispatchHandler environment_push_dispatch_handler;
+
+ template<class SETTINGT>
+ class LLSettingsInjected : public SETTINGT
+ {
+ public:
+ typedef std::shared_ptr<LLSettingsInjected<SETTINGT> > ptr_t;
+
+ LLSettingsInjected(typename SETTINGT::ptr_t source) :
+ SETTINGT(),
+ mSource(source),
+ mLastSourceHash(0),
+ mLastHash(0)
+ {}
+
+ virtual ~LLSettingsInjected() {};
+
+ typename SETTINGT::ptr_t getSource() const { return this->mSource; }
+ void setSource(const typename SETTINGT::ptr_t &source)
+ {
+ if (source.get() == this) // do not set a source to itself.
+ return;
+ this->mSource = source;
+ this->setDirtyFlag(true);
+ this->mLastSourceHash = 0;
+ }
+
+ virtual bool isDirty() const override { return SETTINGT::isDirty() || (this->mSource->isDirty()); }
+ virtual bool isVeryDirty() const override { return SETTINGT::isVeryDirty() || (this->mSource->isVeryDirty()); }
+
+ void injectSetting(const std::string keyname, LLSD value, LLUUID experience_id, F32Seconds transition)
+ {
+ if (transition > 0.1)
+ {
+ typename Injection::ptr_t injection = std::make_shared<Injection>(transition, keyname, value, true, experience_id);
+
+ mInjections.push_back(injection);
+ std::stable_sort(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a, const typename Injection::ptr_t &b) { return a->mTimeRemaining < b->mTimeRemaining; });
+ }
+ else
+ {
+ mOverrideValues[keyname] = value;
+ mOverrideExps[keyname] = experience_id;
+ this->setDirtyFlag(true);
+ }
+ }
+
+ void removeInjection(const std::string keyname, LLUUID experience, LLSettingsBase::Seconds transition)
+ {
+ injections_t injections_buf;
+ for (auto it = mInjections.begin(); it != mInjections.end(); it++)
+ {
+ if ((keyname.empty() || ((*it)->mKeyName == keyname)) &&
+ (experience.isNull() || (experience == (*it)->mExperience)))
+ {
+ if (transition != LLEnvironment::TRANSITION_INSTANT)
+ {
+ typename Injection::ptr_t injection = std::make_shared<Injection>(transition, keyname, (*it)->mLastValue, false, LLUUID::null);
+ injections_buf.push_front(injection);
+ }
+ }
+ else
+ {
+ injections_buf.push_front(*it);
+ }
+ }
+ mInjections.clear();
+ mInjections = injections_buf;
+
+ for (auto itexp = mOverrideExps.begin(); itexp != mOverrideExps.end();)
+ {
+ if (experience.isNull() || ((*itexp).second == experience))
+ {
+ if (transition != LLEnvironment::TRANSITION_INSTANT)
+ {
+ typename Injection::ptr_t injection = std::make_shared<Injection>(transition, (*itexp).first, mOverrideValues[(*itexp).first], false, LLUUID::null);
+ mInjections.push_front(injection);
+ }
+ mOverrideValues.erase((*itexp).first);
+ mOverrideExps.erase(itexp++);
+ }
+ else
+ ++itexp;
+ }
+ std::stable_sort(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a, const typename Injection::ptr_t &b) { return a->mTimeRemaining < b->mTimeRemaining; });
+ }
+
+ void removeInjections(LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ removeInjection(std::string(), experience_id, transition);
+ }
+
+ void injectExperienceValues(LLSD values, LLUUID experience_id, typename LLSettingsBase::Seconds transition)
+ {
+ for (auto it = values.beginMap(); it != values.endMap(); ++it)
+ {
+ injectSetting((*it).first, (*it).second, experience_id, transition);
+ }
+ this->setDirtyFlag(true);
+ }
+
+ void applyInjections(LLSettingsBase::Seconds delta)
+ {
+ this->mSettings = this->mSource->getSettings();
+
+ for (auto ito = mOverrideValues.beginMap(); ito != mOverrideValues.endMap(); ++ito)
+ {
+ this->mSettings[(*ito).first] = (*ito).second;
+ }
+
+ const LLSettingsBase::stringset_t &slerps = this->getSlerpKeys();
+ const LLSettingsBase::stringset_t &skips = this->getSkipInterpolateKeys();
+ const LLSettingsBase::stringset_t &specials = this->getSpecialKeys();
+
+ typename injections_t::iterator it;
+ for (it = mInjections.begin(); it != mInjections.end(); ++it)
+ {
+ std::string key_name = (*it)->mKeyName;
+
+ LLSD value = this->mSettings[key_name];
+ LLSD target = (*it)->mValue;
+
+ if ((*it)->mFirstTime)
+ (*it)->mFirstTime = false;
+ else
+ (*it)->mTimeRemaining -= delta;
+
+ typename LLSettingsBase::BlendFactor mix = 1.0f - ((*it)->mTimeRemaining.value() / (*it)->mTransition.value());
+
+ if (mix >= 1.0)
+ {
+ if ((*it)->mBlendIn)
+ {
+ mOverrideValues[key_name] = target;
+ mOverrideExps[key_name] = (*it)->mExperience;
+ this->mSettings[key_name] = target;
+ }
+ else
+ {
+ this->mSettings.erase(key_name);
+ }
+ }
+ else if (specials.find(key_name) != specials.end())
+ {
+ updateSpecial(*it, mix);
+ }
+ else if (skips.find(key_name) == skips.end())
+ {
+ if (!(*it)->mBlendIn)
+ mix = 1.0 - mix;
+ (*it)->mLastValue = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, slerps);
+ this->mSettings[key_name] = (*it)->mLastValue;
+ }
+ }
+
+ size_t hash = this->getHash();
+
+ if (hash != mLastHash)
+ {
+ this->setDirtyFlag(true);
+ mLastHash = hash;
+ }
+
+ it = mInjections.begin();
+ it = std::find_if(mInjections.begin(), mInjections.end(), [](const typename Injection::ptr_t &a) { return a->mTimeRemaining > 0.0f; });
+
+ if (it != mInjections.begin())
+ {
+ mInjections.erase(mInjections.begin(), mInjections.end());
+ }
+
+ }
+
+ bool hasInjections() const
+ {
+ return (!mInjections.empty() || (mOverrideValues.size() > 0));
+ }
+
+ protected:
+ struct Injection
+ {
+ Injection(typename LLSettingsBase::Seconds transition, const std::string &keyname, LLSD value, bool blendin, LLUUID experince, S32 index = -1) :
+ mTransition(transition),
+ mTimeRemaining(transition),
+ mKeyName(keyname),
+ mValue(value),
+ mExperience(experince),
+ mIndex(index),
+ mBlendIn(blendin),
+ mFirstTime(true)
+ {}
+
+ typename LLSettingsBase::Seconds mTransition;
+ typename LLSettingsBase::Seconds mTimeRemaining;
+ std::string mKeyName;
+ LLSD mValue;
+ LLSD mLastValue;
+ LLUUID mExperience;
+ S32 mIndex;
+ bool mBlendIn;
+ bool mFirstTime;
+
+ typedef std::shared_ptr<Injection> ptr_t;
+ };
+
+
+ virtual void updateSettings() override
+ {
+ static LLFrameTimer timer;
+
+ if (!this->mSource)
+ return;
+
+ // clears the dirty flag on this object. Need to prevent triggering
+ // more calls into this updateSettings
+ LLSettingsBase::updateSettings();
+
+ resetSpecial();
+
+ if (this->mSource->isDirty())
+ {
+ this->mSource->updateSettings();
+ }
+
+ typename LLSettingsBase::Seconds delta(timer.getElapsedTimeAndResetF32());
+
+
+ SETTINGT::updateSettings();
+
+ if (!mInjections.empty())
+ this->setDirtyFlag(true);
+ }
+
+ LLSettingsBase::stringset_t getSpecialKeys() const;
+ void resetSpecial();
+ void updateSpecial(const typename Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix);
+
+ private:
+ typedef std::map<std::string, LLUUID> key_to_expid_t;
+ typedef std::deque<typename Injection::ptr_t> injections_t;
+
+ size_t mLastSourceHash;
+ size_t mLastHash;
+ typename SETTINGT::ptr_t mSource;
+ injections_t mInjections;
+ LLSD mOverrideValues;
+ key_to_expid_t mOverrideExps;
+ };
+
+ template<>
+ LLSettingsBase::stringset_t LLSettingsInjected<LLSettingsVOSky>::getSpecialKeys() const
+ {
+ static LLSettingsBase::stringset_t specialSet;
+
+ if (specialSet.empty())
+ {
+ specialSet.insert(SETTING_BLOOM_TEXTUREID);
+ specialSet.insert(SETTING_RAINBOW_TEXTUREID);
+ specialSet.insert(SETTING_HALO_TEXTUREID);
+ specialSet.insert(SETTING_CLOUD_TEXTUREID);
+ specialSet.insert(SETTING_MOON_TEXTUREID);
+ specialSet.insert(SETTING_SUN_TEXTUREID);
+ }
+ return specialSet;
+ }
+
+ template<>
+ LLSettingsBase::stringset_t LLSettingsInjected<LLSettingsVOWater>::getSpecialKeys() const
+ {
+ static stringset_t specialSet;
+
+ if (specialSet.empty())
+ {
+ specialSet.insert(SETTING_TRANSPARENT_TEXTURE);
+ specialSet.insert(SETTING_NORMAL_MAP);
+ }
+ return specialSet;
+ }
+
+ template<>
+ void LLSettingsInjected<LLSettingsVOSky>::resetSpecial()
+ {
+ mNextSunTextureId.setNull();
+ mNextMoonTextureId.setNull();
+ mNextCloudTextureId.setNull();
+ mNextBloomTextureId.setNull();
+ mNextRainbowTextureId.setNull();
+ mNextHaloTextureId.setNull();
+ setBlendFactor(0.0f);
+ }
+
+ template<>
+ void LLSettingsInjected<LLSettingsVOWater>::resetSpecial()
+ {
+ mNextNormalMapID.setNull();
+ mNextTransparentTextureID.setNull();
+ setBlendFactor(0.0f);
+ }
+
+ template<>
+ void LLSettingsInjected<LLSettingsVOSky>::updateSpecial(const typename LLSettingsInjected<LLSettingsVOSky>::Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix)
+ {
+ if (injection->mKeyName == SETTING_SUN_TEXTUREID)
+ {
+ mNextSunTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_MOON_TEXTUREID)
+ {
+ mNextMoonTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_CLOUD_TEXTUREID)
+ {
+ mNextCloudTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_BLOOM_TEXTUREID)
+ {
+ mNextBloomTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_RAINBOW_TEXTUREID)
+ {
+ mNextRainbowTextureId = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_HALO_TEXTUREID)
+ {
+ mNextHaloTextureId = injection->mValue.asUUID();
+ }
+
+ // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along.
+ if (getBlendFactor() < mix)
+ {
+ setBlendFactor(mix);
+ }
+ }
+
+ template<>
+ void LLSettingsInjected<LLSettingsVOWater>::updateSpecial(const typename LLSettingsInjected<LLSettingsVOWater>::Injection::ptr_t &injection, typename LLSettingsBase::BlendFactor mix)
+ {
+ if (injection->mKeyName == SETTING_NORMAL_MAP)
+ {
+ mNextNormalMapID = injection->mValue.asUUID();
+ }
+ else if (injection->mKeyName == SETTING_TRANSPARENT_TEXTURE)
+ {
+ mNextTransparentTextureID = injection->mValue.asUUID();
+ }
+
+ // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along.
+ if (getBlendFactor() < mix)
+ {
+ setBlendFactor(mix);
+ }
+ }
+
+ typedef LLSettingsInjected<LLSettingsVOSky> LLSettingsInjectedSky;
+ typedef LLSettingsInjected<LLSettingsVOWater> LLSettingsInjectedWater;
+
+ //=====================================================================
+ class DayInjection : public LLEnvironment::DayInstance
+ {
+ friend class InjectedTransition;
+
+ public:
+ typedef std::shared_ptr<DayInjection> ptr_t;
+ typedef std::weak_ptr<DayInjection> wptr_t;
+
+ DayInjection(LLEnvironment::EnvSelection_t env);
+ virtual ~DayInjection();
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta) override;
+
+ void setInjectedDay(const LLSettingsDay::ptr_t &pday, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void setInjectedSky(const LLSettingsSky::ptr_t &psky, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void setInjectedWater(const LLSettingsWater::ptr_t &pwater, LLUUID experience_id, LLSettingsBase::Seconds transition);
+
+ void injectSkySettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition);
+ void injectWaterSettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition);
+
+ void clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time);
+
+ virtual void animate() override;
+
+ LLEnvironment::DayInstance::ptr_t getBaseDayInstance() const { return mBaseDayInstance; }
+ void setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday);
+
+ S32 countExperiencesActive() const { return mActiveExperiences.size(); }
+
+ bool isOverriddenSky() const { return !mSkyExperience.isNull(); }
+ bool isOverriddenWater() const { return !mWaterExperience.isNull(); }
+
+ bool hasInjections() const;
+
+ void testExperiencesOnParcel(S32 parcel_id);
+ private:
+ static void testExperiencesOnParcelCoro(wptr_t that, S32 parcel_id);
+
+
+ void animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition);
+ void animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition);
+
+ void onEnvironmentChanged(LLEnvironment::EnvSelection_t env);
+ void onParcelChange();
+
+ void checkExperience();
+
+
+ LLEnvironment::DayInstance::ptr_t mBaseDayInstance;
+
+ LLSettingsInjectedSky::ptr_t mInjectedSky;
+ LLSettingsInjectedWater::ptr_t mInjectedWater;
+ std::set<LLUUID> mActiveExperiences;
+ LLUUID mDayExperience;
+ LLUUID mSkyExperience;
+ LLUUID mWaterExperience;
+ LLEnvironment::connection_t mEnvChangeConnection;
+ boost::signals2::connection mParcelChangeConnection;
+ };
+
+ class InjectedTransition : public LLEnvironment::DayTransition
+ {
+ public:
+ InjectedTransition(const DayInjection::ptr_t &injection, const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, DayInstance::ptr_t &end, LLSettingsDay::Seconds time):
+ LLEnvironment::DayTransition(skystart, waterstart, end, time),
+ mInjection(injection)
+ { }
+ virtual ~InjectedTransition() { };
+
+ virtual void animate() override;
+
+ protected:
+ DayInjection::ptr_t mInjection;
+ };
+
+}
+
+//=========================================================================
+const F64Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
+const F64Seconds LLEnvironment::TRANSITION_FAST(1.0f);
+const F64Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
+const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
+const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
+
+const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
+const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
+
+const S32 LLEnvironment::NO_TRACK(-1);
+const S32 LLEnvironment::NO_VERSION(-3); // For viewer sided change, like ENV_LOCAL. -3 since -1 and -2 are taken by parcel initial server/viewer version
+const S32 LLEnvironment::VERSION_CLEANUP(-4); // for cleanups
+
+const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
+
+
+const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01);
+const U32 LLEnvironment::DayInstance::NO_ANIMATE_WATER(0x02);
+
+std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel)
+{
+#define RTNENUM(E) case LLEnvironment::E: return #E
+ switch (sel){
+ RTNENUM(ENV_EDIT);
+ RTNENUM(ENV_LOCAL);
+ RTNENUM(ENV_PUSH);
+ RTNENUM(ENV_PARCEL);
+ RTNENUM(ENV_REGION);
+ RTNENUM(ENV_DEFAULT);
+ RTNENUM(ENV_END);
+ RTNENUM(ENV_CURRENT);
+ RTNENUM(ENV_NONE);
+ default:
+ return llformat("Unknown(%d)", sel);
+ }
+#undef RTNENUM
+}
+
+
+//-------------------------------------------------------------------------
+LLEnvironment::LLEnvironment():
+ mCloudScrollDelta(),
+ mCloudScrollPaused(false),
+ mSelectedSky(),
+ mSelectedWater(),
+ mSelectedDay(),
+ mSelectedEnvironment(LLEnvironment::ENV_LOCAL),
+ mCurrentTrack(1),
+ mEditorCounter(0),
+ mShowSunBeacon(false),
+ mShowMoonBeacon(false)
+{
+}
+
+void LLEnvironment::initSingleton()
+{
+ LLSettingsSky::ptr_t p_default_sky = LLSettingsVOSky::buildDefaultSky();
+ LLSettingsWater::ptr_t p_default_water = LLSettingsVOWater::buildDefaultWater();
+
+ mCurrentEnvironment = std::make_shared<DayInstance>(ENV_DEFAULT);
+ mCurrentEnvironment->setSky(p_default_sky);
+ mCurrentEnvironment->setWater(p_default_water);
+
+ mEnvironments[ENV_DEFAULT] = mCurrentEnvironment;
+
+ requestRegion();
+
+ gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
+
+ //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer.
+ // We need to know new env version to fix this, without it we can only do full re-request
+ // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
+ LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
+ gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
+
+ gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
+
+ if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT))
+ {
+ gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler);
+ }
+
+ LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; });
+}
+
+void LLEnvironment::cleanupSingleton()
+{
+ LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
+}
+
+LLEnvironment::~LLEnvironment()
+{
+}
+
+bool LLEnvironment::canEdit() const
+{
+ return true;
+}
+
+LLSettingsSky::ptr_t LLEnvironment::getCurrentSky() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+
+ if (!psky && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
+ {
+ for (int idx = 0; idx < ENV_END; ++idx)
+ {
+ if (mEnvironments[idx]->getSky())
+ {
+ psky = mEnvironments[idx]->getSky();
+ break;
+ }
+ }
+ }
+ return psky;
+}
+
+LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const
+{
+ LLSettingsWater::ptr_t pwater = mCurrentEnvironment->getWater();
+
+ if (!pwater && mCurrentEnvironment->getEnvironmentSelection() >= ENV_EDIT)
+ {
+ for (int idx = 0; idx < ENV_END; ++idx)
+ {
+ if (mEnvironments[idx]->getWater())
+ {
+ pwater = mEnvironments[idx]->getWater();
+ break;
+ }
+ }
+ }
+ return pwater;
+}
+
+void LayerConfigToDensityLayer(const LLSD& layerConfig, DensityLayer& layerOut)
+{
+ layerOut.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ layerOut.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ layerOut.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ layerOut.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ layerOut.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+}
+
+void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky)
+{
+ settingsOut.m_skyBottomRadius = psky->getSkyBottomRadius();
+ settingsOut.m_skyTopRadius = psky->getSkyTopRadius();
+ settingsOut.m_sunArcRadians = psky->getSunArcRadians();
+ settingsOut.m_mieAnisotropy = psky->getMieAnisotropy();
+
+ LLSD rayleigh = psky->getRayleighConfigs();
+ settingsOut.m_rayleighProfile.clear();
+ for (LLSD::array_iterator itf = rayleigh.beginArray(); itf != rayleigh.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_rayleighProfile.push_back(layer);
+ }
+
+ LLSD mie = psky->getMieConfigs();
+ settingsOut.m_mieProfile.clear();
+ for (LLSD::array_iterator itf = mie.beginArray(); itf != mie.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_mieProfile.push_back(layer);
+ }
+ settingsOut.m_mieAnisotropy = psky->getMieAnisotropy();
+
+ LLSD absorption = psky->getAbsorptionConfigs();
+ settingsOut.m_absorptionProfile.clear();
+ for (LLSD::array_iterator itf = absorption.beginArray(); itf != absorption.endArray(); ++itf)
+ {
+ DensityLayer layer;
+ LLSD& layerConfig = (*itf);
+ LayerConfigToDensityLayer(layerConfig, layer);
+ settingsOut.m_absorptionProfile.push_back(layer);
+ }
+}
+
+bool LLEnvironment::canAgentUpdateParcelEnvironment() const
+{
+ LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+ return canAgentUpdateParcelEnvironment(parcel);
+}
+
+
+bool LLEnvironment::canAgentUpdateParcelEnvironment(LLParcel *parcel) const
+{
+ if (!parcel)
+ return false;
+
+ if (!LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ return false;
+
+ if (gAgent.isGodlike())
+ return true;
+
+ if (!parcel->getRegionAllowEnvironmentOverride())
+ return false;
+
+ return LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_ALLOW_ENVIRONMENT);
+}
+
+bool LLEnvironment::canAgentUpdateRegionEnvironment() const
+{
+ if (gAgent.isGodlike())
+ return true;
+
+ return gAgent.canManageEstate();
+}
+
+bool LLEnvironment::isExtendedEnvironmentEnabled() const
+{
+ return !gAgent.getRegionCapability("ExtEnvironment").empty();
+}
+
+bool LLEnvironment::isInventoryEnabled() const
+{
+ return (!gAgent.getRegionCapability("UpdateSettingsAgentInventory").empty() &&
+ !gAgent.getRegionCapability("UpdateSettingsTaskInventory").empty());
+}
+
+void LLEnvironment::onRegionChange()
+{
+// if (gAgent.getRegionCapability("ExperienceQuery").empty())
+// {
+// // for now environmental experiences do not survive region crossings
+ clearExperienceEnvironment(LLUUID::null, TRANSITION_DEFAULT);
+// }
+
+ LLViewerRegion* cur_region = gAgent.getRegion();
+ if (!cur_region)
+ {
+ return;
+ }
+ if (!cur_region->capabilitiesReceived())
+ {
+ cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id) { LLEnvironment::instance().requestRegion(); });
+ return;
+ }
+ requestRegion();
+}
+
+void LLEnvironment::onParcelChange()
+{
+ S32 parcel_id(INVALID_PARCEL_ID);
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (parcel)
+ {
+ parcel_id = parcel->getLocalID();
+ }
+
+ requestParcel(parcel_id);
+}
+
+//-------------------------------------------------------------------------
+F32 LLEnvironment::getCamHeight() const
+{
+ return (mCurrentEnvironment->getSky()->getDomeOffset() * mCurrentEnvironment->getSky()->getDomeRadius());
+}
+
+F32 LLEnvironment::getWaterHeight() const
+{
+ LLViewerRegion* cur_region = gAgent.getRegion();
+ return cur_region ? cur_region->getWaterHeight() : DEFAULT_WATER_HEIGHT;
+}
+
+bool LLEnvironment::getIsSunUp() const
+{
+ if (!mCurrentEnvironment || !mCurrentEnvironment->getSky())
+ return false;
+ return mCurrentEnvironment->getSky()->getIsSunUp();
+}
+
+bool LLEnvironment::getIsMoonUp() const
+{
+ if (!mCurrentEnvironment || !mCurrentEnvironment->getSky())
+ return false;
+ return mCurrentEnvironment->getSky()->getIsMoonUp();
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LLSettingsBase::Seconds transition, bool forced)
+{
+ mSelectedEnvironment = env;
+ updateEnvironment(transition, forced);
+ LL_DEBUGS("ENVIRONMENT") << "Setting environment " << env_selection_to_string(env) << " with transition: " << transition << LL_ENDL;
+}
+
+bool LLEnvironment::hasEnvironment(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT) || (!mEnvironments[env]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnvironment::EnvSelection_t env, bool create /*= false*/)
+{
+ DayInstance::ptr_t environment = mEnvironments[env];
+ if (create)
+ {
+ if (environment)
+ environment = environment->clone();
+ else
+ {
+ if (env == ENV_PUSH)
+ environment = std::make_shared<DayInjection>(env);
+ else
+ environment = std::make_shared<DayInstance>(env);
+ }
+ mEnvironments[env] = environment;
+ }
+
+ return environment;
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return;
+ }
+
+ logEnvironment(env, pday, env_version);
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+ environment->clear();
+ environment->setDay(pday, daylength, dayoffset);
+ environment->setSkyTrack(mCurrentTrack);
+ environment->animate();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, env_version);
+}
+
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironment::fixedEnvironment_t fixed, S32 env_version)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return;
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+
+
+ if (fixed.first)
+ {
+ logEnvironment(env, fixed.first, env_version);
+ environment->setSky(fixed.first);
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else if (!environment->getSky())
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL;
+ environment->setSky(mCurrentEnvironment->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+
+ if (fixed.second)
+ {
+ logEnvironment(env, fixed.second, env_version);
+ environment->setWater(fixed.second);
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else if (!environment->getWater())
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL;
+ environment->setWater(mCurrentEnvironment->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, env_version);
+}
+
+void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
+{
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (env == ENV_DEFAULT)
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to set default environment. Not allowed." << LL_ENDL;
+ return;
+ }
+
+ if (!settings)
+ {
+ clearEnvironment(env);
+ return;
+ }
+
+ if (settings->getSettingsType() == "daycycle")
+ {
+ LLSettingsDay::Seconds daylength(LLSettingsDay::DEFAULT_DAYLENGTH);
+ LLSettingsDay::Seconds dayoffset(LLSettingsDay::DEFAULT_DAYOFFSET);
+ if (environment)
+ {
+ daylength = environment->getDayLength();
+ dayoffset = environment->getDayOffset();
+ }
+ setEnvironment(env, std::static_pointer_cast<LLSettingsDay>(settings), daylength, dayoffset);
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ fixedEnvironment_t fixedenv(std::static_pointer_cast<LLSettingsSky>(settings), LLSettingsWater::ptr_t());
+ setEnvironment(env, fixedenv);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ fixedEnvironment_t fixedenv(LLSettingsSky::ptr_t(), std::static_pointer_cast<LLSettingsWater>(settings));
+ setEnvironment(env, fixedenv);
+ }
+}
+
+void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
+{
+ setEnvironment(env, assetId, TRANSITION_DEFAULT, env_version);
+}
+
+void LLEnvironment::setEnvironment(EnvSelection_t env,
+ const LLUUID &assetId,
+ LLSettingsBase::Seconds transition,
+ S32 env_version)
+{
+ LLSettingsVOBase::getSettingsAsset(assetId,
+ [this, env, env_version, transition](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ {
+ onSetEnvAssetLoaded(env, asset_id, settings, transition, status, env_version);
+ });
+}
+
+void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
+ LLUUID asset_id,
+ LLSettingsBase::ptr_t settings,
+ LLSettingsBase::Seconds transition,
+ S32 status,
+ S32 env_version)
+{
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = asset_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ LL_DEBUGS("ENVIRONMENT") << "Failed to find settings for " << env_selection_to_string(env) << ", asset_id: " << asset_id << LL_ENDL;
+ return;
+ }
+ LL_DEBUGS("ENVIRONMENT") << "Loaded asset: " << asset_id << LL_ENDL;
+
+ setEnvironment(env, settings);
+ updateEnvironment(transition);
+}
+
+void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("ENVIRONMENT") << "Cleaning environment " << env_selection_to_string(env) << LL_ENDL;
+
+ mEnvironments[env].reset();
+
+ if (!mSignalEnvChanged.empty())
+ mSignalEnvChanged(env, VERSION_CLEANUP);
+}
+
+void LLEnvironment::logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
+{
+ LL_DEBUGS("ENVIRONMENT") << "Setting Day environment " << env_selection_to_string(env) << " with version(update type): " << env_version << LL_NEWLINE;
+ // code between LL_DEBUGS and LL_ENDL won't execute unless log is enabled
+ if (settings)
+ {
+ LLUUID asset_id = settings->getAssetId();
+ if (asset_id.notNull())
+ {
+ LL_CONT << "Asset id: " << asset_id << LL_NEWLINE;
+ }
+
+ LLUUID id = settings->getId(); // Not in use?
+ if (id.notNull())
+ {
+ LL_CONT << "Settings id: " << id << LL_NEWLINE;
+ }
+
+ LL_CONT << "Name: " << settings->getName() << LL_NEWLINE
+ << "Type: " << settings->getSettingsType() << LL_NEWLINE
+ << "Flags: " << settings->getFlags(); // Not in use?
+ }
+ else
+ {
+ LL_CONT << "Empty settings!";
+ }
+ LL_CONT << LL_ENDL;
+}
+
+LLSettingsDay::ptr_t LLEnvironment::getEnvironmentDay(LLEnvironment::EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return environment->getDayCycle();
+
+ return LLSettingsDay::ptr_t();
+}
+
+LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayLength(EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return LLSettingsDay::Seconds(0);
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return environment->getDayLength();
+
+ return LLSettingsDay::Seconds(0);
+}
+
+LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayOffset(EnvSelection_t env)
+{
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return LLSettingsDay::Seconds(0);
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+ if (environment)
+ return environment->getDayOffset();
+
+ return LLSettingsDay::Seconds(0);
+}
+
+
+LLEnvironment::fixedEnvironment_t LLEnvironment::getEnvironmentFixed(LLEnvironment::EnvSelection_t env, bool resolve)
+{
+ if ((env == ENV_CURRENT) || resolve)
+ {
+ fixedEnvironment_t fixed;
+ for (S32 idx = ((resolve) ? env : mSelectedEnvironment); idx < ENV_END; ++idx)
+ {
+ if (fixed.first && fixed.second)
+ break;
+
+ if (idx == ENV_EDIT)
+ continue; // skip the edit environment.
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(static_cast<EnvSelection_t>(idx));
+ if (environment)
+ {
+ if (!fixed.first)
+ fixed.first = environment->getSky();
+ if (!fixed.second)
+ fixed.second = environment->getWater();
+ }
+ }
+
+ if (!fixed.first || !fixed.second)
+ LL_WARNS("ENVIRONMENT") << "Can not construct complete fixed environment. Missing Sky and/or Water." << LL_ENDL;
+
+ return fixed;
+ }
+
+ if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
+ return fixedEnvironment_t();
+ }
+
+ DayInstance::ptr_t environment = getEnvironmentInstance(env);
+
+ if (environment)
+ return fixedEnvironment_t(environment->getSky(), environment->getWater());
+
+ return fixedEnvironment_t();
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getSelectedEnvironmentInstance()
+{
+ for (S32 idx = mSelectedEnvironment; idx < ENV_DEFAULT; ++idx)
+ {
+ if (mEnvironments[idx])
+ return mEnvironments[idx];
+ }
+
+ return mEnvironments[ENV_DEFAULT];
+}
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::getSharedEnvironmentInstance()
+{
+ for (S32 idx = ENV_PARCEL; idx < ENV_DEFAULT; ++idx)
+ {
+ if (mEnvironments[idx])
+ return mEnvironments[idx];
+ }
+
+ return mEnvironments[ENV_DEFAULT];
+}
+
+void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool forced)
+{
+ DayInstance::ptr_t pinstance = getSelectedEnvironmentInstance();
+
+ if ((mCurrentEnvironment != pinstance) || forced)
+ {
+ if (transition != TRANSITION_INSTANT)
+ {
+ DayInstance::ptr_t trans = std::make_shared<DayTransition>(
+ mCurrentEnvironment->getSky(), mCurrentEnvironment->getWater(), pinstance, transition);
+
+ trans->animate();
+
+ mCurrentEnvironment = trans;
+ }
+ else
+ {
+ mCurrentEnvironment = pinstance;
+ }
+ }
+}
+
+LLVector4 LLEnvironment::toCFR(const LLVector3 vec) const
+{
+ LLVector4 vec_cfr(vec.mV[1], vec.mV[0], vec.mV[2], 0.0f);
+ return vec_cfr;
+}
+
+LLVector4 LLEnvironment::toLightNorm(const LLVector3 vec) const
+{
+ LLVector4 vec_ogl(vec.mV[1], vec.mV[2], vec.mV[0], 0.0f);
+ return vec_ogl;
+}
+
+LLVector3 LLEnvironment::getLightDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, 1);
+ }
+ return psky->getLightDirection();
+}
+
+LLVector3 LLEnvironment::getSunDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, 1);
+ }
+ return psky->getSunDirection();
+}
+
+LLVector3 LLEnvironment::getMoonDirection() const
+{
+ LLSettingsSky::ptr_t psky = mCurrentEnvironment->getSky();
+ if (!psky)
+ {
+ return LLVector3(0, 0, -1);
+ }
+ return psky->getMoonDirection();
+}
+
+LLVector4 LLEnvironment::getLightDirectionCFR() const
+{
+ LLVector3 light_direction = getLightDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getSunDirectionCFR() const
+{
+ LLVector3 light_direction = getSunDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getMoonDirectionCFR() const
+{
+ LLVector3 light_direction = getMoonDirection();
+ LLVector4 light_direction_cfr = toCFR(light_direction);
+ return light_direction_cfr;
+}
+
+LLVector4 LLEnvironment::getClampedLightNorm() const
+{
+ LLVector3 light_direction = getLightDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getClampedSunNorm() const
+{
+ LLVector3 light_direction = getSunDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getClampedMoonNorm() const
+{
+ LLVector3 light_direction = getMoonDirection();
+ if (light_direction.mV[2] < -0.1f)
+ {
+ light_direction.mV[2] = -0.1f;
+ }
+ return toLightNorm(light_direction);
+}
+
+LLVector4 LLEnvironment::getRotatedLightNorm() const
+{
+ LLVector3 light_direction = getLightDirection();
+ light_direction *= LLQuaternion(-mLastCamYaw, LLVector3(0.f, 1.f, 0.f));
+ return toLightNorm(light_direction);
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::update(const LLViewerCamera * cam)
+{
+ LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE);
+ //F32Seconds now(LLDate::now().secondsSinceEpoch());
+ static LLFrameTimer timer;
+
+ F32Seconds delta(timer.getElapsedTimeAndResetF32());
+
+ {
+ DayInstance::ptr_t keeper = mCurrentEnvironment;
+ // make sure the current environment does not go away until applyTimeDelta is done.
+ mCurrentEnvironment->applyTimeDelta(delta);
+
+ }
+ // update clouds, sun, and general
+ updateCloudScroll();
+
+ // cache this for use in rotating the rotated light vec for shader param updates later...
+ mLastCamYaw = cam->getYaw() + SUN_DELTA_YAW;
+
+ stop_glerror();
+
+ // *TODO: potential optimization - this block may only need to be
+ // executed some of the time. For example for water shaders only.
+ {
+ LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
+ end_shaders = LLViewerShaderMgr::instance()->endShaders();
+ for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
+ {
+ if ((shaders_iter->mProgramObject != 0)
+ && (gPipeline.canUseWindLightShaders()
+ || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
+ {
+ shaders_iter->mUniformsDirty = TRUE;
+ }
+ }
+ }
+}
+
+void LLEnvironment::updateCloudScroll()
+{
+ // This is a function of the environment rather than the sky, since it should
+ // persist through sky transitions.
+ static LLTimer s_cloud_timer;
+
+ F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();
+
+ if (mCurrentEnvironment->getSky() && !mCloudScrollPaused)
+ {
+ LLVector2 cloud_delta = static_cast<F32>(delta_t)* (mCurrentEnvironment->getSky()->getCloudScrollRate()) / 100.0;
+ mCloudScrollDelta += cloud_delta;
+ }
+
+}
+
+// static
+void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting)
+{
+ LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE);
+
+ //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
+ LLSettingsBase::parammapping_t params = psetting->getParameterMap();
+ for (auto &it: params)
+ {
+ LLSD value;
+ // legacy first since it contains ambient color and we prioritize value from legacy, see getAmbientColor()
+ if (psetting->mSettings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE].has(it.first))
+ {
+ value = psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE][it.first];
+ }
+ else if (psetting->mSettings.has(it.first))
+ {
+ value = psetting->mSettings[it.first];
+ }
+ else
+ {
+ // We need to reset shaders, use defaults
+ value = it.second.getDefaultValue();
+ }
+
+ LLSD::Type setting_type = value.type();
+ stop_glerror();
+ switch (setting_type)
+ {
+ case LLSD::TypeInteger:
+ shader->uniform1i(it.second.getShaderKey(), value.asInteger());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+ case LLSD::TypeReal:
+ shader->uniform1f(it.second.getShaderKey(), value.asReal());
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+
+ case LLSD::TypeBoolean:
+ shader->uniform1i(it.second.getShaderKey(), value.asBoolean() ? 1 : 0);
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
+ break;
+
+ case LLSD::TypeArray:
+ {
+ LLVector4 vect4(value);
+ //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
+ shader->uniform4fv(it.second.getShaderKey(), 1, vect4.mV);
+ break;
+ }
+
+ // case LLSD::TypeMap:
+ // case LLSD::TypeString:
+ // case LLSD::TypeUUID:
+ // case LLSD::TypeURI:
+ // case LLSD::TypeBinary:
+ // case LLSD::TypeDate:
+ default:
+ break;
+ }
+ stop_glerror();
+ }
+ //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
+
+ psetting->applySpecial(shader);
+}
+
+void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
+{
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getWater());
+ updateGLVariablesForSettings(shader, mCurrentEnvironment->getSky());
+}
+
+void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition)
+{
+ if (!gAgent.getRegion())
+ {
+ return;
+ }
+ // mRegionId id can be null, no specification as to why and if it's valid so check valid ids only
+ if (gAgent.getRegion()->getRegionID() != envinfo->mRegionId && envinfo->mRegionId.notNull())
+ {
+ LL_INFOS("ENVIRONMENT") << "Requested environmend region id: " << envinfo->mRegionId << " agent is on: " << gAgent.getRegion()->getRegionID() << LL_ENDL;
+ return;
+ }
+
+ if (envinfo->mParcelId == INVALID_PARCEL_ID)
+ {
+ // the returned info applies to an entire region.
+ if (!envinfo->mDayCycle)
+ {
+ clearEnvironment(ENV_PARCEL);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
+ updateEnvironment();
+ }
+ else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
+ || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
+ updateEnvironment();
+ }
+ else
+ {
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
+ mTrackAltitudes = envinfo->mAltitudes;
+ }
+
+ LL_DEBUGS("ENVIRONMENT") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL;
+ }
+ else
+ {
+ LLParcel *parcel = LLViewerParcelMgr::instance().getAgentParcel();
+ LL_DEBUGS("ENVIRONMENT") << "Have parcel environment #" << envinfo->mParcelId << LL_ENDL;
+ if (parcel && (parcel->getLocalID() != parcel_id))
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Requested parcel #" << parcel_id << " agent is on " << parcel->getLocalID() << LL_ENDL;
+ return;
+ }
+
+ if (!envinfo->mDayCycle)
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Clearing environment on parcel #" << parcel_id << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ }
+ else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
+ || envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid day cycle for parcel #" << parcel_id << LL_ENDL;
+ clearEnvironment(ENV_PARCEL);
+ }
+ else
+ {
+ setEnvironment(ENV_PARCEL, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
+ }
+ }
+
+ updateEnvironment(transition);
+}
+
+void LLEnvironment::adjustRegionOffset(F32 adjust)
+{
+ if (isExtendedEnvironmentEnabled())
+ {
+ LL_WARNS("ENVIRONMENT") << "Attempt to adjust region offset on EEP region. Legacy regions only." << LL_ENDL;
+ }
+
+ if (mEnvironments[ENV_REGION])
+ {
+ F32 day_length = mEnvironments[ENV_REGION]->getDayLength();
+ F32 day_offset = mEnvironments[ENV_REGION]->getDayOffset();
+
+ F32 day_adjustment = adjust * day_length;
+
+ day_offset += day_adjustment;
+ if (day_offset < 0.0f)
+ day_offset = day_length + day_offset;
+ mEnvironments[ENV_REGION]->setDayOffset(LLSettingsBase::Seconds(day_offset));
+ }
+}
+
+//=========================================================================
+void LLEnvironment::requestRegion(environment_apply_fn cb)
+{
+ requestParcel(INVALID_PARCEL_ID, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ if (!isExtendedEnvironmentEnabled())
+ {
+ LL_WARNS("ENVIRONMENT") << "attempt to apply asset id to region not supporting it." << LL_ENDL;
+ LLNotificationsUtil::add("NoEnvironmentSettings");
+ return;
+ }
+
+ updateParcel(INVALID_PARCEL_ID, asset_id, display_name, track_num, day_length, day_offset, flags, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, psky, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(INVALID_PARCEL_ID, pwater, day_length, day_offset, altitudes, cb);
+}
+
+
+void LLEnvironment::resetRegion(environment_apply_fn cb)
+{
+ resetParcel(INVALID_PARCEL_ID, cb);
+}
+
+void LLEnvironment::requestParcel(S32 parcel_id, environment_apply_fn cb)
+{
+ if (!isExtendedEnvironmentEnabled())
+ { /*TODO: When EEP is live on the entire grid, this can go away. */
+ if (parcel_id == INVALID_PARCEL_ID)
+ {
+ if (!cb)
+ {
+ LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT;
+ cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo)
+ {
+ clearEnvironment(ENV_PARCEL);
+ recordEnvironment(pid, envinfo, transition);
+ };
+ }
+
+ LLEnvironmentRequest::initiate(cb);
+ }
+ else if (cb)
+ cb(parcel_id, EnvironmentInfo::ptr_t());
+ return;
+ }
+
+ if (!cb)
+ {
+ LLSettingsBase::Seconds transition = LLViewerParcelMgr::getInstance()->getTeleportInProgress() ? TRANSITION_FAST : TRANSITION_DEFAULT;
+ cb = [this, transition](S32 pid, EnvironmentInfo::ptr_t envinfo) { recordEnvironment(pid, envinfo, transition); };
+ }
+
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroRequestEnvironment",
+ [this, parcel_id, cb]() { coroRequestEnvironment(parcel_id, cb); });
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ UpdateInfo::ptr_t updates(std::make_shared<UpdateInfo>(asset_id, display_name, day_length, day_offset, altitudes, flags));
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, track_num, updates, cb]() { coroUpdateEnvironment(parcel_id, track_num, updates, cb); });
+}
+
+void LLEnvironment::onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes)
+{
+ if (status)
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to get settings asset with id " << asset_id << "!" << LL_ENDL;
+ LLNotificationsUtil::add("FailedToLoadSettingsApply");
+ return;
+ }
+
+ LLSettingsDay::ptr_t pday;
+
+ if (settings->getSettingsType() == "daycycle")
+ pday = std::static_pointer_cast<LLSettingsDay>(settings);
+ else
+ {
+ pday = createDayCycleFromEnvironment( (parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, settings);
+ }
+
+ if (!pday)
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to construct day around " << asset_id << "!" << LL_ENDL;
+ LLNotificationsUtil::add("FailedToBuildSettingsDay");
+ return;
+ }
+
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, psky);
+ pday->setFlag(psky->getFlags());
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ LLSettingsDay::ptr_t pday = createDayCycleFromEnvironment((parcel_id == INVALID_PARCEL_ID) ? ENV_REGION : ENV_PARCEL, pwater);
+ pday->setFlag(pwater->getFlags());
+ updateParcel(parcel_id, pday, day_length, day_offset, altitudes, cb);
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 track_num, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ UpdateInfo::ptr_t updates(std::make_shared<UpdateInfo>(pday, day_length, day_offset, altitudes));
+
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroUpdateEnvironment",
+ [this, parcel_id, track_num, updates, cb]() { coroUpdateEnvironment(parcel_id, track_num, updates, cb); });
+}
+
+void LLEnvironment::updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, LLEnvironment::altitudes_vect_t altitudes, environment_apply_fn cb)
+{
+ updateParcel(parcel_id, pday, NO_TRACK, day_length, day_offset, altitudes, cb);
+}
+
+
+
+void LLEnvironment::resetParcel(S32 parcel_id, environment_apply_fn cb)
+{
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironment::coroResetEnvironment",
+ [this, parcel_id, cb]() { coroResetEnvironment(parcel_id, NO_TRACK, cb); });
+}
+
+void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ LL_DEBUGS("ENVIRONMENT") << "Requesting for parcel_id=" << parcel_id << LL_ENDL;
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ std::stringstream query;
+
+ query << "?parcelid=" << parcel_id;
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+ // results that come back may contain the new settings
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+}
+
+void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInfo::ptr_t updates, environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ LLSD body(LLSD::emptyMap());
+ body[KEY_ENVIRONMENT] = LLSD::emptyMap();
+
+ if (track_no == NO_TRACK)
+ { // day length and offset are only applicable if we are addressing the entire day cycle.
+ if (updates->mDayLength > 0)
+ body[KEY_ENVIRONMENT][KEY_DAYLENGTH] = updates->mDayLength;
+ if (updates->mDayOffset > 0)
+ body[KEY_ENVIRONMENT][KEY_DAYOFFSET] = updates->mDayOffset;
+
+ if ((parcel_id == INVALID_PARCEL_ID) && (updates->mAltitudes.size() == 3))
+ { // only test for altitude changes if we are changing the region.
+ body[KEY_ENVIRONMENT][KEY_TRACKALTS] = LLSD::emptyArray();
+ for (S32 i = 0; i < 3; ++i)
+ {
+ body[KEY_ENVIRONMENT][KEY_TRACKALTS][i] = updates->mAltitudes[i];
+ }
+ }
+ }
+
+ if (updates->mDayp)
+ body[KEY_ENVIRONMENT][KEY_DAYCYCLE] = updates->mDayp->getSettings();
+ else if (!updates->mSettingsAsset.isNull())
+ {
+ body[KEY_ENVIRONMENT][KEY_DAYASSET] = updates->mSettingsAsset;
+ if (!updates->mDayName.empty())
+ body[KEY_ENVIRONMENT][KEY_DAYNAME] = updates->mDayName;
+ }
+
+ body[KEY_ENVIRONMENT][KEY_FLAGS] = LLSD::Integer(updates->mFlags);
+ //_WARNS("ENVIRONMENT") << "Body = " << body << LL_ENDL;
+
+ if ((parcel_id != INVALID_PARCEL_ID) || (track_no != NO_TRACK))
+ {
+ std::stringstream query;
+ query << "?";
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ query << "parcelid=" << parcel_id;
+
+ if (track_no != NO_TRACK)
+ query << "&";
+ }
+ if (track_no != NO_TRACK)
+ {
+ query << "trackno=" << track_no;
+ }
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, url, body);
+ // results that come back may contain the new settings
+
+ LLSD notify;
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't update Windlight settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = result["message"].asString();
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+ if (!notify.isUndefined())
+ {
+ LLNotificationsUtil::add("WLRegionApplyFail", notify);
+ //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+ }
+}
+
+void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environment_apply_fn apply)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ResetEnvironment", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
+ if (url.empty())
+ return;
+
+ if ((parcel_id != INVALID_PARCEL_ID) || (track_no != NO_TRACK))
+ {
+ std::stringstream query;
+ query << "?";
+
+ if (parcel_id != INVALID_PARCEL_ID)
+ {
+ query << "parcelid=" << parcel_id;
+
+ if (track_no != NO_TRACK)
+ query << "&";
+ }
+ if (track_no != NO_TRACK)
+ {
+ query << "trackno=" << track_no;
+ }
+ url += query.str();
+ }
+
+ LLSD result = httpAdapter->deleteAndSuspend(httpRequest, url);
+ // results that come back may contain the new settings
+
+ LLSD notify;
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if ((!status) || !result["success"].asBoolean())
+ {
+ LL_WARNS("ENVIRONMENT") << "Couldn't reset Windlight settings in " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
+
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = result["message"].asString();
+ }
+ else
+ {
+ LLSD environment = result[KEY_ENVIRONMENT];
+ if (environment.isDefined() && apply)
+ {
+ EnvironmentInfo::ptr_t envinfo = LLEnvironment::EnvironmentInfo::extract(environment);
+ apply(parcel_id, envinfo);
+ }
+ }
+
+ if (!notify.isUndefined())
+ {
+ LLNotificationsUtil::add("WLRegionApplyFail", notify);
+ //LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+ }
+
+}
+
+
+//=========================================================================
+
+LLEnvironment::EnvironmentInfo::EnvironmentInfo():
+ mParcelId(INVALID_PARCEL_ID),
+ mRegionId(),
+ mDayLength(0),
+ mDayOffset(0),
+ mDayHash(0),
+ mDayCycle(),
+ mAltitudes({ { 0.0, 0.0, 0.0, 0.0 } }),
+ mIsDefault(false),
+ mIsLegacy(false),
+ mDayCycleName(),
+ mNameList(),
+ mEnvVersion(INVALID_PARCEL_ENVIRONMENT_VERSION)
+{
+}
+
+LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extract(LLSD environment)
+{
+ ptr_t pinfo = std::make_shared<EnvironmentInfo>();
+
+ pinfo->mIsDefault = environment.has(KEY_ISDEFAULT) ? environment[KEY_ISDEFAULT].asBoolean() : true;
+ pinfo->mParcelId = environment.has(KEY_PARCELID) ? environment[KEY_PARCELID].asInteger() : INVALID_PARCEL_ID;
+ pinfo->mRegionId = environment.has(KEY_REGIONID) ? environment[KEY_REGIONID].asUUID() : LLUUID::null;
+ pinfo->mIsLegacy = false;
+
+ if (environment.has(KEY_TRACKALTS))
+ {
+ for (int idx = 0; idx < 3; idx++)
+ {
+ pinfo->mAltitudes[idx+1] = environment[KEY_TRACKALTS][idx].asReal();
+ }
+ pinfo->mAltitudes[0] = 0;
+ }
+
+ if (environment.has(KEY_DAYCYCLE))
+ {
+ pinfo->mDayCycle = LLSettingsVODay::buildFromEnvironmentMessage(environment[KEY_DAYCYCLE]);
+ pinfo->mDayLength = LLSettingsDay::Seconds(environment.has(KEY_DAYLENGTH) ? environment[KEY_DAYLENGTH].asInteger() : -1);
+ pinfo->mDayOffset = LLSettingsDay::Seconds(environment.has(KEY_DAYOFFSET) ? environment[KEY_DAYOFFSET].asInteger() : -1);
+ pinfo->mDayHash = environment.has(KEY_DAYHASH) ? environment[KEY_DAYHASH].asInteger() : 0;
+ }
+ else
+ {
+ pinfo->mDayLength = LLEnvironment::instance().getEnvironmentDayLength(ENV_REGION);
+ pinfo->mDayOffset = LLEnvironment::instance().getEnvironmentDayOffset(ENV_REGION);
+ }
+
+ if (environment.has(KEY_DAYASSET))
+ {
+ pinfo->mAssetId = environment[KEY_DAYASSET].asUUID();
+ }
+
+ if (environment.has(KEY_DAYNAMES))
+ {
+ LLSD daynames = environment[KEY_DAYNAMES];
+ if (daynames.isArray())
+ {
+ pinfo->mDayCycleName.clear();
+ for (S32 index = 0; index < pinfo->mNameList.size(); ++index)
+ {
+ pinfo->mNameList[index] = daynames[index].asString();
+ }
+ }
+ else if (daynames.isString())
+ {
+ for (std::string &name: pinfo->mNameList)
+ {
+ name.clear();
+ }
+
+ pinfo->mDayCycleName = daynames.asString();
+ }
+ }
+ else if (pinfo->mDayCycle)
+ {
+ pinfo->mDayCycleName = pinfo->mDayCycle->getName();
+ }
+
+
+ if (environment.has(KEY_ENVVERSION))
+ {
+ LLSD version = environment[KEY_ENVVERSION];
+ pinfo->mEnvVersion = version.asInteger();
+ }
+ else
+ {
+ // can be used for region, but versions should be same
+ pinfo->mEnvVersion = pinfo->mIsDefault ? UNSET_PARCEL_ENVIRONMENT_VERSION : INVALID_PARCEL_ENVIRONMENT_VERSION;
+ }
+
+ return pinfo;
+}
+
+
+LLEnvironment::EnvironmentInfo::ptr_t LLEnvironment::EnvironmentInfo::extractLegacy(LLSD legacy)
+{
+ if (!legacy.isArray() || !legacy[0].has("regionID"))
+ {
+ LL_WARNS("ENVIRONMENT") << "Invalid legacy settings for environment: " << legacy << LL_ENDL;
+ return ptr_t();
+ }
+
+ ptr_t pinfo = std::make_shared<EnvironmentInfo>();
+
+ pinfo->mIsDefault = false;
+ pinfo->mParcelId = INVALID_PARCEL_ID;
+ pinfo->mRegionId = legacy[0]["regionID"].asUUID();
+ pinfo->mIsLegacy = true;
+
+ pinfo->mDayLength = LLSettingsDay::DEFAULT_DAYLENGTH;
+ pinfo->mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET;
+ pinfo->mDayCycle = LLSettingsVODay::buildFromLegacyMessage(pinfo->mRegionId, legacy[1], legacy[2], legacy[3]);
+ if (pinfo->mDayCycle)
+ pinfo->mDayHash = pinfo->mDayCycle->getHash();
+
+ pinfo->mAltitudes[0] = 0;
+ pinfo->mAltitudes[2] = 10001;
+ pinfo->mAltitudes[3] = 10002;
+ pinfo->mAltitudes[4] = 10003;
+
+ return pinfo;
+}
+
+//=========================================================================
+LLSettingsWater::ptr_t LLEnvironment::createWaterFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsWater::ptr_t water = LLSettingsVOWater::buildFromLegacyPresetFile(name, path, messages);
+
+ if (!water)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return water;
+}
+
+LLSettingsSky::ptr_t LLEnvironment::createSkyFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildFromLegacyPresetFile(name, path, messages);
+ if (!sky)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return sky;
+}
+
+LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromLegacyPreset(const std::string filename, LLSD &messages)
+{
+ std::string name(gDirUtilp->getBaseFileName(filename, true));
+ std::string path(gDirUtilp->getDirName(filename));
+
+ LLSettingsDay::ptr_t day = LLSettingsVODay::buildFromLegacyPresetFile(name, path, messages);
+ if (!day)
+ {
+ messages["NAME"] = name;
+ messages["FILE"] = filename;
+ }
+ return day;
+}
+
+LLSettingsDay::ptr_t LLEnvironment::createDayCycleFromEnvironment(EnvSelection_t env, LLSettingsBase::ptr_t settings)
+{
+ std::string type(settings->getSettingsType());
+
+ if (type == "daycycle")
+ return std::static_pointer_cast<LLSettingsDay>(settings);
+
+ if ((env != ENV_PARCEL) && (env != ENV_REGION))
+ {
+ LL_WARNS("ENVIRONMENT") << "May only create from parcel or region environment." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t day = this->getEnvironmentDay(env);
+ if (!day && (env == ENV_PARCEL))
+ {
+ day = this->getEnvironmentDay(ENV_REGION);
+ }
+
+ if (!day)
+ {
+ LL_WARNS("ENVIRONMENT") << "Could not retrieve existing day settings." << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ day = day->buildClone();
+
+ if (type == "sky")
+ {
+ for (S32 idx = 1; idx < LLSettingsDay::TRACK_MAX; ++idx)
+ day->clearCycleTrack(idx);
+ day->setSettingsAtKeyframe(settings, 0.0f, 1);
+ }
+ else if (type == "water")
+ {
+ day->clearCycleTrack(LLSettingsDay::TRACK_WATER);
+ day->setSettingsAtKeyframe(settings, 0.0f, LLSettingsDay::TRACK_WATER);
+ }
+
+ return day;
+}
+
+void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)
+{
+ S32 trackno = calculateSkyTrackForAltitude(localpos.mV[VZ]);
+ if (trackno == mCurrentTrack)
+ return;
+
+ mCurrentTrack = trackno;
+ for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env)
+ {
+ if (mEnvironments[env])
+ mEnvironments[env]->setSkyTrack(mCurrentTrack);
+ }
+}
+
+S32 LLEnvironment::calculateSkyTrackForAltitude(F64 altitude)
+{
+ auto it = std::find_if_not(mTrackAltitudes.begin(), mTrackAltitudes.end(), [altitude](F32 test) { return altitude > test; });
+
+ if (it == mTrackAltitudes.begin())
+ return 1;
+ else if (it == mTrackAltitudes.end())
+ return 4;
+
+ return std::min(static_cast<S32>(std::distance(mTrackAltitudes.begin(), it)), 4);
+}
+
+//-------------------------------------------------------------------------
+void LLEnvironment::handleEnvironmentPush(LLSD &message)
+{
+ // Log the experience message
+ LLExperienceLog::instance().handleExperienceMessage(message);
+
+ std::string action = message[KEY_ACTION].asString();
+ LLUUID experience_id = message[KEY_EXPERIENCEID].asUUID();
+ LLSD action_data = message[KEY_ACTIONDATA];
+ F32 transition_time = action_data[KEY_TRANSITIONTIME].asReal();
+
+ //TODO: Check here that the viewer thinks the experience is still valid.
+
+
+ if (action == ACTION_CLEARENVIRONMENT)
+ {
+ handleEnvironmentPushClear(experience_id, action_data, transition_time);
+ }
+ else if (action == ACTION_PUSHFULLENVIRONMENT)
+ {
+ handleEnvironmentPushFull(experience_id, action_data, transition_time);
+ }
+ else if (action == ACTION_PUSHPARTIALENVIRONMENT)
+ {
+ handleEnvironmentPushPartial(experience_id, action_data, transition_time);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT", "GENERICMESSAGES") << "Unknown environment push action '" << action << "'" << LL_ENDL;
+ }
+}
+
+void LLEnvironment::handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ LLUUID asset_id(message[KEY_ASSETID].asUUID());
+
+ setExperienceEnvironment(experience_id, asset_id, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::handleEnvironmentPushPartial(LLUUID experience_id, LLSD &message, F32 transition)
+{
+ LLSD settings(message["settings"]);
+
+ if (settings.isUndefined())
+ return;
+
+ setExperienceEnvironment(experience_id, settings, LLSettingsBase::Seconds(transition));
+}
+
+void LLEnvironment::clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time)
+{
+ DayInjection::ptr_t injection = std::dynamic_pointer_cast<DayInjection>(getEnvironmentInstance(ENV_PUSH));
+ if (injection)
+ {
+ injection->clearInjections(experience_id, transition_time);
+ }
+
+}
+
+void LLEnvironment::setSharedEnvironment()
+{
+ clearEnvironment(LLEnvironment::ENV_LOCAL);
+ setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ updateEnvironment();
+}
+
+void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time)
+{
+ LLSettingsVOBase::getSettingsAsset(asset_id,
+ [this, experience_id, transition_time](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ {
+ onSetExperienceEnvAssetLoaded(experience_id, settings, transition_time, status);
+ });
+
+
+}
+
+void LLEnvironment::onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettingsBase::ptr_t settings, F32 transition_time, S32 status)
+{
+ DayInjection::ptr_t environment = std::dynamic_pointer_cast<DayInjection>(getEnvironmentInstance(ENV_PUSH));
+ bool updateenvironment(false);
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = experience_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ return;
+ }
+
+ if (!environment)
+ {
+ environment = std::dynamic_pointer_cast<DayInjection>(getEnvironmentInstance(ENV_PUSH, true));
+ updateenvironment = true;
+ }
+
+ if (settings->getSettingsType() == "daycycle")
+ {
+ environment->setInjectedDay(std::static_pointer_cast<LLSettingsDay>(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ environment->setInjectedSky(std::static_pointer_cast<LLSettingsSky>(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ environment->setInjectedWater(std::static_pointer_cast<LLSettingsWater>(settings), experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (updateenvironment)
+ updateEnvironment(TRANSITION_INSTANT, true);
+}
+
+
+void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F32 transition_time)
+{
+ LLSD sky(data["sky"]);
+ LLSD water(data["water"]);
+
+ if (sky.isUndefined() && water.isUndefined())
+ {
+ clearExperienceEnvironment(experience_id, LLSettingsBase::Seconds(transition_time));
+ return;
+ }
+
+ DayInjection::ptr_t environment = std::dynamic_pointer_cast<DayInjection>(getEnvironmentInstance(ENV_PUSH));
+ bool updateenvironment(false);
+
+ if (!environment)
+ {
+ environment = std::dynamic_pointer_cast<DayInjection>(getEnvironmentInstance(ENV_PUSH, true));
+ updateenvironment = true;
+ }
+
+ if (!sky.isUndefined())
+ {
+ environment->injectSkySettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (!water.isUndefined())
+ {
+ environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ }
+
+ if (updateenvironment)
+ updateEnvironment(TRANSITION_INSTANT, true);
+
+}
+
+void LLEnvironment::listenExperiencePump(const LLSD &message)
+{
+ LLUUID experience_id = message["experience"];
+ LLSD data = message[experience_id.asString()];
+ std::string permission(data["permission"].asString());
+
+ if ((permission == "Forget") || (permission == "Block"))
+ {
+ clearExperienceEnvironment(experience_id, (permission == "Block") ? TRANSITION_INSTANT : TRANSITION_FAST);
+ }
+}
+
+//=========================================================================
+LLEnvironment::DayInstance::DayInstance(EnvSelection_t env) :
+ mDayCycle(),
+ mSky(),
+ mWater(),
+ mDayLength(LLSettingsDay::DEFAULT_DAYLENGTH),
+ mDayOffset(LLSettingsDay::DEFAULT_DAYOFFSET),
+ mBlenderSky(),
+ mBlenderWater(),
+ mInitialized(false),
+ mSkyTrack(1),
+ mEnv(env),
+ mAnimateFlags(0)
+{ }
+
+
+LLEnvironment::DayInstance::ptr_t LLEnvironment::DayInstance::clone() const
+{
+ ptr_t environment = std::make_shared<DayInstance>(mEnv);
+
+ environment->mDayCycle = mDayCycle;
+ environment->mSky = mSky;
+ environment->mWater = mWater;
+ environment->mDayLength = mDayLength;
+ environment->mDayOffset = mDayOffset;
+ environment->mBlenderSky = mBlenderSky;
+ environment->mBlenderWater = mBlenderWater;
+ environment->mInitialized = mInitialized;
+ environment->mSkyTrack = mSkyTrack;
+ environment->mAnimateFlags = mAnimateFlags;
+
+ return environment;
+}
+
+bool LLEnvironment::DayInstance::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ ptr_t keeper(shared_from_this()); // makes sure that this does not go away while it is being worked on.
+
+ bool changed(false);
+ if (!mInitialized)
+ initialize();
+
+ if (mBlenderSky)
+ changed |= mBlenderSky->applyTimeDelta(delta);
+ if (mBlenderWater)
+ changed |= mBlenderWater->applyTimeDelta(delta);
+ return changed;
+}
+
+void LLEnvironment::DayInstance::setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset)
+{
+ mInitialized = false;
+
+ mAnimateFlags = 0;
+
+ mDayCycle = pday;
+ mDayLength = daylength;
+ mDayOffset = dayoffset;
+
+ mBlenderSky.reset();
+ mBlenderWater.reset();
+
+ mSky = LLSettingsVOSky::buildDefaultSky();
+ mWater = LLSettingsVOWater::buildDefaultWater();
+
+ animate();
+}
+
+
+void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
+{
+ mInitialized = false;
+
+ bool different_sky = mSky != psky;
+
+ mSky = psky;
+ mSky->mReplaced |= different_sky;
+ mSky->update();
+ mBlenderSky.reset();
+
+ if (gAtmosphere)
+ {
+ AtmosphericModelSettings settings;
+ LLEnvironment::getAtmosphericModelSettings(settings, psky);
+ gAtmosphere->configureAtmosphericModel(settings);
+ }
+}
+
+void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater)
+{
+ mInitialized = false;
+
+ bool different_water = mWater != pwater;
+ mWater = pwater;
+ mWater->mReplaced |= different_water;
+ mWater->update();
+ mBlenderWater.reset();
+}
+
+void LLEnvironment::DayInstance::initialize()
+{
+ mInitialized = true;
+
+ if (!mWater)
+ mWater = LLSettingsVOWater::buildDefaultWater();
+ if (!mSky)
+ mSky = LLSettingsVOSky::buildDefaultSky();
+}
+
+void LLEnvironment::DayInstance::clear()
+{
+ mDayCycle.reset();
+ mSky.reset();
+ mWater.reset();
+ mDayLength = LLSettingsDay::DEFAULT_DAYLENGTH;
+ mDayOffset = LLSettingsDay::DEFAULT_DAYOFFSET;
+ mBlenderSky.reset();
+ mBlenderWater.reset();
+ mSkyTrack = 1;
+}
+
+void LLEnvironment::DayInstance::setSkyTrack(S32 trackno)
+{
+ mSkyTrack = trackno;
+ if (mBlenderSky)
+ {
+ mBlenderSky->switchTrack(trackno, 0.0);
+ }
+}
+
+void LLEnvironment::DayInstance::setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend)
+{
+ mBlenderSky = skyblend;
+ mBlenderWater = waterblend;
+}
+
+LLSettingsBase::TrackPosition LLEnvironment::DayInstance::getProgress() const
+{
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+ now += mDayOffset;
+
+ if ((mDayLength <= 0) || !mDayCycle)
+ return -1.0f; // no actual day cycle.
+
+ return convert_time_to_position(now, mDayLength);
+}
+
+LLSettingsBase::TrackPosition LLEnvironment::DayInstance::secondsToKeyframe(LLSettingsDay::Seconds seconds)
+{
+ return convert_time_to_position(seconds, mDayLength);
+}
+
+void LLEnvironment::DayInstance::animate()
+{
+ LLSettingsBase::Seconds now(LLDate::now().secondsSinceEpoch());
+
+ now += mDayOffset;
+
+ if (!mDayCycle)
+ return;
+
+ if (!(mAnimateFlags & NO_ANIMATE_WATER))
+ {
+ LLSettingsDay::CycleTrack_t &wtrack = mDayCycle->getCycleTrack(0);
+
+ if (wtrack.empty())
+ {
+ mWater.reset();
+ mBlenderWater.reset();
+ }
+ else
+ {
+ mWater = LLSettingsVOWater::buildDefaultWater();
+ mBlenderWater = std::make_shared<LLTrackBlenderLoopingTime>(mWater, mDayCycle, 0,
+ mDayLength, mDayOffset, DEFAULT_UPDATE_THRESHOLD);
+ }
+ }
+
+ if (!(mAnimateFlags & NO_ANIMATE_SKY))
+ {
+ // sky, initialize to track 1
+ LLSettingsDay::CycleTrack_t &track = mDayCycle->getCycleTrack(1);
+
+ if (track.empty())
+ {
+ mSky.reset();
+ mBlenderSky.reset();
+ }
+ else
+ {
+ mSky = LLSettingsVOSky::buildDefaultSky();
+ mBlenderSky = std::make_shared<LLTrackBlenderLoopingTime>(mSky, mDayCycle, 1,
+ mDayLength, mDayOffset, DEFAULT_UPDATE_THRESHOLD);
+ mBlenderSky->switchTrack(mSkyTrack, 0.0);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+LLEnvironment::DayTransition::DayTransition(const LLSettingsSky::ptr_t &skystart,
+ const LLSettingsWater::ptr_t &waterstart, LLEnvironment::DayInstance::ptr_t &end, LLSettingsDay::Seconds time) :
+ DayInstance(ENV_NONE),
+ mStartSky(skystart),
+ mStartWater(waterstart),
+ mNextInstance(end),
+ mTransitionTime(time)
+{
+
+}
+
+bool LLEnvironment::DayTransition::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+{
+ bool changed(false);
+
+ changed = mNextInstance->applyTimeDelta(delta);
+ changed |= DayInstance::applyTimeDelta(delta);
+ return changed;
+}
+
+void LLEnvironment::DayTransition::animate()
+{
+ mNextInstance->animate();
+
+ mWater = mStartWater->buildClone();
+ mBlenderWater = std::make_shared<LLSettingsBlenderTimeDelta>(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime);
+ mBlenderWater->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderWater.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ LLEnvironment::instance().mCurrentEnvironment = mNextInstance;
+ else
+ setWater(mNextInstance->getWater());
+ });
+
+ mSky = mStartSky->buildClone();
+ mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime);
+ mBlenderSky->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderSky.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ LLEnvironment::instance().mCurrentEnvironment = mNextInstance;
+ else
+ setSky(mNextInstance->getSky());
+ });
+}
+
+void LLEnvironment::saveToSettings()
+{
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (user_dir.empty())
+ {
+ // not logged in
+ return;
+ }
+ bool has_data = false;
+
+ if (gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin"))
+ {
+ DayInstance::ptr_t environment = getEnvironmentInstance(ENV_LOCAL);
+ if (environment)
+ {
+ // Environment is 'layered'. No data in ENV_LOCAL means we are using parcel/region
+ // Store local environment for next session
+ LLSD env_data;
+
+ LLSettingsDay::ptr_t day = environment->getDayCycle();
+ if (day)
+ {
+ const std::string name = day->getName();
+ const LLUUID asset_id = day->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["day_id"] = asset_id;
+ env_data["day_length"] = LLSD::Integer(environment->getDayLength());
+ env_data["day_offset"] = LLSD::Integer(environment->getDayOffset());
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["day_llsd"] = day->getSettings();
+ env_data["day_length"] = LLSD::Integer(environment->getDayLength());
+ env_data["day_offset"] = LLSD::Integer(environment->getDayOffset());
+ has_data = true;
+ }
+ }
+
+ LLSettingsSky::ptr_t sky = environment->getSky();
+ if ((environment->getFlags() & DayInstance::NO_ANIMATE_SKY) && sky)
+ {
+ const std::string name = sky->getName();
+ const LLUUID asset_id = sky->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["sky_id"] = asset_id;
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["sky_llsd"] = sky->getSettings();
+ has_data = true;
+ }
+ has_data = true;
+ }
+
+ LLSettingsWater::ptr_t water = environment->getWater();
+ if ((environment->getFlags() & DayInstance::NO_ANIMATE_WATER) && water)
+ {
+ const std::string name = water->getName();
+ const LLUUID asset_id = water->getAssetId();
+ if (asset_id.notNull())
+ {
+ // just save the id
+ env_data["water_id"] = asset_id;
+ has_data = true;
+ }
+ else if (!name.empty() && name != LLSettingsBase::DEFAULT_SETTINGS_NAME)
+ {
+ // This setting was created locally and was not saved
+ // The only option is to save the whole thing
+ env_data["water_llsd"] = water->getSettings();
+ has_data = true;
+ }
+ }
+
+ std::string user_filepath = user_dir + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE;
+ llofstream out(user_filepath.c_str(), std::ios_base::out | std::ios_base::binary);
+ if (out.good())
+ {
+ LLSDSerialize::toBinary(env_data, out);
+ out.close();
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to open " << user_filepath << " for output." << LL_ENDL;
+ }
+ }
+ }
+
+ if (!has_data)
+ {
+ LLFile::remove(user_dir + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE, ENOENT);
+ }
+}
+
+void LLEnvironment::loadSkyWaterFromSettings(const LLSD &env_data, bool &valid, bool &assets_present)
+{
+ if (env_data.has("sky_id"))
+ {
+ // causes asset loaded callback and an update
+ setEnvironment(ENV_LOCAL, env_data["sky_id"].asUUID());
+ valid = true;
+ assets_present = true;
+ }
+ else if (env_data.has("sky_llsd"))
+ {
+ LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildSky(env_data["sky_llsd"]);
+ setEnvironment(ENV_LOCAL, sky);
+ valid = true;
+ }
+
+ if (env_data.has("water_id"))
+ {
+ // causes asset loaded callback and an update
+ setEnvironment(ENV_LOCAL, env_data["water_id"].asUUID());
+ valid = true;
+ assets_present = true;
+ }
+ else if (env_data.has("water_llsd"))
+ {
+ LLSettingsWater::ptr_t sky = LLSettingsVOWater::buildWater(env_data["water_llsd"]);
+ setEnvironment(ENV_LOCAL, sky);
+ valid = true;
+ }
+}
+
+bool LLEnvironment::loadFromSettings()
+{
+ if (!gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin"))
+ {
+ return false;
+ }
+
+ std::string user_path = gDirUtilp->getLindenUserDir();
+ if (user_path.empty())
+ {
+ LL_WARNS("ENVIRONMENT") << "Can't load previous environment, Environment was initialized before user logged in" << LL_ENDL;
+ return false;
+ }
+ std::string user_filepath(user_path + gDirUtilp->getDirDelimiter() + LOCAL_ENV_STORAGE_FILE);
+ if (!gDirUtilp->fileExists(user_filepath))
+ {
+ // No previous environment
+ return false;
+ }
+
+ LLSD env_data;
+ llifstream file(user_filepath.c_str(), std::ios_base::in | std::ios_base::binary);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromBinary(env_data, file, LLSDSerialize::SIZE_UNLIMITED);
+ if (env_data.isUndefined())
+ {
+ LL_WARNS("ENVIRONMENT") << "error loading " << user_filepath << LL_ENDL;
+ return false;
+ }
+ else
+ {
+ LL_INFOS("ENVIRONMENT") << "Loaded previous session environment from: " << user_filepath << LL_ENDL;
+ }
+ file.close();
+ }
+ else
+ {
+ LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL;
+ }
+
+ if (!env_data.isMap() || env_data.emptyMap())
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL;
+ return false;
+ }
+
+ bool valid = false;
+ bool has_assets = false;
+
+ if (env_data.has("day_id"))
+ {
+ LLUUID assetId = env_data["day_id"].asUUID();
+
+ LLSettingsVOBase::getSettingsAsset(assetId,
+ [this, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+ {
+ // Day should be always applied first,
+ // otherwise it will override sky or water that was set earlier
+ // so wait for asset to load before applying sky/water
+ onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, TRANSITION_DEFAULT, status, NO_VERSION);
+ bool valid = false, has_assets = false;
+ loadSkyWaterFromSettings(env_data, valid, has_assets);
+ if (!has_assets && valid)
+ {
+ // Settings were loaded from file without having an asset, needs update
+ // otherwise update will be done by asset callback
+ updateEnvironment(TRANSITION_DEFAULT, true);
+ }
+ });
+ // bail early, everything have to be done at callback
+ return true;
+ }
+ else if (env_data.has("day_llsd"))
+ {
+ S32 length = env_data["day_length"].asInteger();
+ S32 offset = env_data["day_offset"].asInteger();
+ LLSettingsDay::ptr_t pday = LLSettingsVODay::buildDay(env_data["day_llsd"]);
+ setEnvironment(ENV_LOCAL, pday, LLSettingsDay::Seconds(length), LLSettingsDay::Seconds(offset));
+ valid = true;
+ }
+
+ loadSkyWaterFromSettings(env_data, valid, has_assets);
+
+ if (valid && !has_assets)
+ {
+ // Settings were loaded from file without having an asset, needs update
+ // otherwise update will be done by asset callback
+ updateEnvironment(TRANSITION_DEFAULT, true);
+ }
+ return valid;
+}
+
+void LLEnvironment::saveBeaconsState()
+{
+ if (mEditorCounter == 0)
+ {
+ mShowSunBeacon = gSavedSettings.getBOOL("sunbeacon");
+ mShowMoonBeacon = gSavedSettings.getBOOL("moonbeacon");
+ }
+ ++mEditorCounter;
+}
+void LLEnvironment::revertBeaconsState()
+{
+ --mEditorCounter;
+ if (mEditorCounter == 0)
+ {
+ gSavedSettings.setBOOL("sunbeacon", mShowSunBeacon && gSavedSettings.getBOOL("sunbeacon"));
+ gSavedSettings.setBOOL("moonbeacon", mShowMoonBeacon && gSavedSettings.getBOOL("moonbeacon"));
+ }
+}
+
+//=========================================================================
+LLTrackBlenderLoopingManual::LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno) :
+ LLSettingsBlender(target, LLSettingsBase::ptr_t(), LLSettingsBase::ptr_t()),
+ mDay(day),
+ mTrackNo(trackno),
+ mPosition(0.0)
+{
+ LLSettingsDay::TrackBound_t initial = getBoundingEntries(mPosition);
+
+ if (initial.first != mEndMarker)
+ { // No frames in track
+ mInitial = (*initial.first).second;
+ mFinal = (*initial.second).second;
+
+ LLSD initSettings = mInitial->getSettings();
+ mTarget->replaceSettings(initSettings);
+ }
+}
+
+LLSettingsBase::BlendFactor LLTrackBlenderLoopingManual::setPosition(const LLSettingsBase::TrackPosition& position)
+{
+ mPosition = llclamp(position, 0.0f, 1.0f);
+
+ LLSettingsDay::TrackBound_t bounds = getBoundingEntries(mPosition);
+
+ if (bounds.first == mEndMarker)
+ { // No frames in track.
+ return 0.0;
+ }
+
+ mInitial = (*bounds.first).second;
+ mFinal = (*bounds.second).second;
+
+ F64 spanLength = getSpanLength(bounds);
+
+ F64 spanPos = ((mPosition < (*bounds.first).first) ? (mPosition + 1.0) : mPosition) - (*bounds.first).first;
+
+ if (spanPos > spanLength)
+ {
+ // we are clamping position to 0-1 and spanLength is 1
+ // so don't account for case of spanPos == spanLength
+ spanPos = fmod(spanPos, spanLength);
+ }
+
+ F64 blendf = spanPos / spanLength;
+ return LLSettingsBlender::setBlendFactor(blendf);
+}
+
+void LLTrackBlenderLoopingManual::switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position)
+{
+ mTrackNo = trackno;
+
+ LLSettingsBase::TrackPosition useposition = (position < 0.0) ? mPosition : position;
+
+ setPosition(useposition);
+}
+
+LLSettingsDay::TrackBound_t LLTrackBlenderLoopingManual::getBoundingEntries(F64 position)
+{
+ LLSettingsDay::CycleTrack_t &wtrack = mDay->getCycleTrack(mTrackNo);
+
+ mEndMarker = wtrack.end();
+
+ LLSettingsDay::TrackBound_t bounds = get_bounding_entries(wtrack, position);
+ return bounds;
+}
+
+F64 LLTrackBlenderLoopingManual::getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const
+{
+ return get_wrapping_distance((*bounds.first).first, (*bounds.second).first);
+}
+
+//=========================================================================
+namespace
+{
+ DayInjection::DayInjection(LLEnvironment::EnvSelection_t env):
+ LLEnvironment::DayInstance(env),
+ mBaseDayInstance(),
+ mInjectedSky(),
+ mInjectedWater(),
+ mActiveExperiences(),
+ mDayExperience(),
+ mSkyExperience(),
+ mWaterExperience(),
+ mEnvChangeConnection(),
+ mParcelChangeConnection()
+ {
+ mInjectedSky = std::make_shared<LLSettingsInjectedSky>(LLEnvironment::instance().getCurrentSky());
+ mInjectedWater = std::make_shared<LLSettingsInjectedWater>(LLEnvironment::instance().getCurrentWater());
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+ mSky = mInjectedSky;
+ mWater = mInjectedWater;
+
+ mEnvChangeConnection = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32) { onEnvironmentChanged(env); });
+ mParcelChangeConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
+ }
+
+ DayInjection::~DayInjection()
+ {
+ if (mEnvChangeConnection.connected())
+ mEnvChangeConnection.disconnect();
+ if (mParcelChangeConnection.connected())
+ mParcelChangeConnection.disconnect();
+ }
+
+
+ bool DayInjection::applyTimeDelta(const LLSettingsBase::Seconds& delta)
+ {
+ bool changed(false);
+
+ if (mBaseDayInstance)
+ changed |= mBaseDayInstance->applyTimeDelta(delta);
+ mInjectedSky->applyInjections(delta);
+ mInjectedWater->applyInjections(delta);
+ changed |= LLEnvironment::DayInstance::applyTimeDelta(delta);
+ if (changed)
+ {
+ mInjectedSky->setDirtyFlag(true);
+ mInjectedWater->setDirtyFlag(true);
+ }
+ mInjectedSky->update();
+ mInjectedWater->update();
+
+ if (!hasInjections())
+ { // There are no injections being managed. This should really go away.
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+
+ return changed;
+ }
+
+ void DayInjection::setBaseDayInstance(const LLEnvironment::DayInstance::ptr_t &baseday)
+ {
+ mBaseDayInstance = baseday;
+
+ if (mSkyExperience.isNull())
+ mInjectedSky->setSource(mBaseDayInstance->getSky());
+ if (mWaterExperience.isNull())
+ mInjectedWater->setSource(mBaseDayInstance->getWater());
+ }
+
+
+ bool DayInjection::hasInjections() const
+ {
+ return (!mSkyExperience.isNull() || !mWaterExperience.isNull() || !mDayExperience.isNull() ||
+ mBlenderSky || mBlenderWater || mInjectedSky->hasInjections() || mInjectedWater->hasInjections());
+ }
+
+
+ void DayInjection::testExperiencesOnParcel(S32 parcel_id)
+ {
+ LLCoros::instance().launch("DayInjection::testExperiencesOnParcel",
+ [this, parcel_id]() { DayInjection::testExperiencesOnParcelCoro(std::static_pointer_cast<DayInjection>(this->shared_from_this()), parcel_id); });
+
+ }
+
+ void DayInjection::setInjectedDay(const LLSettingsDay::ptr_t &pday, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mSkyExperience = experience_id;
+ mWaterExperience = experience_id;
+ mDayExperience = experience_id;
+
+ mBaseDayInstance = mBaseDayInstance->clone();
+ mBaseDayInstance->setEnvironmentSelection(LLEnvironment::ENV_NONE);
+ mBaseDayInstance->setDay(pday, mBaseDayInstance->getDayLength(), mBaseDayInstance->getDayOffset());
+ animateSkyChange(mBaseDayInstance->getSky(), transition);
+ animateWaterChange(mBaseDayInstance->getWater(), transition);
+
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::setInjectedSky(const LLSettingsSky::ptr_t &psky, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mSkyExperience = experience_id;
+ mActiveExperiences.insert(experience_id);
+ checkExperience();
+ animateSkyChange(psky, transition);
+ }
+
+ void DayInjection::setInjectedWater(const LLSettingsWater::ptr_t &pwater, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mWaterExperience = experience_id;
+ mActiveExperiences.insert(experience_id);
+ checkExperience();
+ animateWaterChange(pwater, transition);
+ }
+
+ void DayInjection::injectSkySettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mInjectedSky->injectExperienceValues(settings, experience_id, transition);
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::injectWaterSettings(LLSD settings, LLUUID experience_id, LLSettingsBase::Seconds transition)
+ {
+ mInjectedWater->injectExperienceValues(settings, experience_id, transition);
+ mActiveExperiences.insert(experience_id);
+ }
+
+ void DayInjection::clearInjections(LLUUID experience_id, LLSettingsBase::Seconds transition_time)
+ {
+ if ((experience_id.isNull() && !mDayExperience.isNull()) || (experience_id == mDayExperience))
+ {
+ mDayExperience.setNull();
+ if (mSkyExperience == experience_id)
+ mSkyExperience.setNull();
+ if (mWaterExperience == experience_id)
+ mWaterExperience.setNull();
+
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+
+ if (mSkyExperience.isNull())
+ animateSkyChange(mBaseDayInstance->getSky(), transition_time);
+ if (mWaterExperience.isNull())
+ animateWaterChange(mBaseDayInstance->getWater(), transition_time);
+ }
+
+ if ((experience_id.isNull() && !mSkyExperience.isNull()) || (experience_id == mSkyExperience))
+ {
+ mSkyExperience.setNull();
+ animateSkyChange(mBaseDayInstance->getSky(), transition_time);
+ }
+ if ((experience_id.isNull() && !mWaterExperience.isNull()) || (experience_id == mWaterExperience))
+ {
+ mWaterExperience.setNull();
+ animateWaterChange(mBaseDayInstance->getWater(), transition_time);
+ }
+
+ mInjectedSky->removeInjections(experience_id, transition_time);
+ mInjectedWater->removeInjections(experience_id, transition_time);
+
+ if (experience_id.isNull())
+ mActiveExperiences.clear();
+ else
+ mActiveExperiences.erase(experience_id);
+
+ if ((transition_time == LLEnvironment::TRANSITION_INSTANT) && (countExperiencesActive() == 0))
+ { // Only do this if instant and there are no other experiences injecting values.
+ // (otherwise will be handled after transition)
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ }
+
+
+ void DayInjection::testExperiencesOnParcelCoro(wptr_t that, S32 parcel_id)
+ {
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("testExperiencesOnParcelCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ std::string url = gAgent.getRegionCapability("ExperienceQuery");
+
+ if (url.empty())
+ {
+ LL_WARNS("ENVIRONMENT") << "No experience query cap." << LL_ENDL;
+ return; // no checking in this region.
+ }
+
+ {
+ ptr_t thatlock(that);
+ std::stringstream fullurl;
+
+ if (!thatlock)
+ return;
+
+ fullurl << url << "?";
+ fullurl << "parcelid=" << parcel_id;
+
+ for (auto it = thatlock->mActiveExperiences.begin(); it != thatlock->mActiveExperiences.end(); ++it)
+ {
+ if (it != thatlock->mActiveExperiences.begin())
+ fullurl << ",";
+ else
+ fullurl << "&experiences=";
+ fullurl << (*it).asString();
+ }
+ url = fullurl.str();
+ }
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve experience status for parcel." << LL_ENDL;
+ return;
+ }
+
+ {
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+ if (!parcel)
+ return;
+
+ if (parcel_id != parcel->getLocalID())
+ {
+ // Agent no longer on queried parcel.
+ return;
+ }
+ }
+
+
+ LLSD experiences = result["experiences"];
+ {
+ ptr_t thatlock(that);
+ if (!thatlock)
+ return;
+
+ for (LLSD::map_iterator itr = experiences.beginMap(); itr != experiences.endMap(); ++itr)
+ {
+ if (!((*itr).second.asBoolean()))
+ thatlock->clearInjections(LLUUID((*itr).first), LLEnvironment::TRANSITION_FAST);
+
+ }
+ }
+ }
+
+ void DayInjection::animateSkyChange(LLSettingsSky::ptr_t psky, LLSettingsBase::Seconds transition)
+ {
+ if (mInjectedSky.get() == psky.get())
+ { // An attempt to animate to itself... don't do it.
+ return;
+ }
+ if (transition == LLEnvironment::TRANSITION_INSTANT)
+ {
+ mBlenderSky.reset();
+ mInjectedSky->setSource(psky);
+ }
+ else
+ {
+ LLSettingsSky::ptr_t start_sky(mInjectedSky->getSource()->buildClone());
+ LLSettingsSky::ptr_t target_sky(start_sky->buildClone());
+ mInjectedSky->setSource(target_sky);
+
+ mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(target_sky, start_sky, psky, transition);
+ mBlenderSky->setOnFinished(
+ [this, psky](LLSettingsBlender::ptr_t blender)
+ {
+ mBlenderSky.reset();
+ mInjectedSky->setSource(psky);
+ setSky(mInjectedSky);
+ if (!mBlenderWater && (countExperiencesActive() == 0))
+ {
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ });
+ }
+ }
+
+ void DayInjection::animateWaterChange(LLSettingsWater::ptr_t pwater, LLSettingsBase::Seconds transition)
+ {
+ if (mInjectedWater.get() == pwater.get())
+ { // An attempt to animate to itself. Bad idea.
+ return;
+ }
+ if (transition == LLEnvironment::TRANSITION_INSTANT)
+ {
+ mBlenderWater.reset();
+ mInjectedWater->setSource(pwater);
+ }
+ else
+ {
+ LLSettingsWater::ptr_t start_Water(mInjectedWater->getSource()->buildClone());
+ LLSettingsWater::ptr_t scratch_Water(start_Water->buildClone());
+ mInjectedWater->setSource(scratch_Water);
+
+ mBlenderWater = std::make_shared<LLSettingsBlenderTimeDelta>(scratch_Water, start_Water, pwater, transition);
+ mBlenderWater->setOnFinished(
+ [this, pwater](LLSettingsBlender::ptr_t blender)
+ {
+ mBlenderWater.reset();
+ mInjectedWater->setSource(pwater);
+ setWater(mInjectedWater);
+ if (!mBlenderSky && (countExperiencesActive() == 0))
+ {
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_PUSH);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ }
+ });
+ }
+ }
+
+ void DayInjection::onEnvironmentChanged(LLEnvironment::EnvSelection_t env)
+ {
+ if (env >= LLEnvironment::ENV_PARCEL)
+ {
+ LLEnvironment::EnvSelection_t base_env(mBaseDayInstance->getEnvironmentSelection());
+ LLEnvironment::DayInstance::ptr_t nextbase = LLEnvironment::instance().getSharedEnvironmentInstance();
+
+ if ((base_env == LLEnvironment::ENV_NONE) || (nextbase == mBaseDayInstance) ||
+ (!mSkyExperience.isNull() && !mWaterExperience.isNull()))
+ { // base instance completely overridden, or not changed no transition will happen
+ return;
+ }
+
+ LL_WARNS("PUSHENV", "ENVIRONMENT") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
+
+ LLEnvironment::DayInstance::ptr_t trans = std::make_shared<InjectedTransition>(std::static_pointer_cast<DayInjection>(shared_from_this()),
+ mBaseDayInstance->getSky(), mBaseDayInstance->getWater(), nextbase, LLEnvironment::TRANSITION_DEFAULT);
+
+ trans->animate();
+ setBaseDayInstance(trans);
+ }
+ }
+
+ void DayInjection::onParcelChange()
+ {
+ S32 parcel_id(INVALID_PARCEL_ID);
+ LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ if (!parcel)
+ return;
+
+ parcel_id = parcel->getLocalID();
+
+ testExperiencesOnParcel(parcel_id);
+ }
+
+ void DayInjection::checkExperience()
+ {
+ if ((!mDayExperience.isNull()) && (mSkyExperience != mDayExperience) && (mWaterExperience != mDayExperience))
+ { // There was a day experience but we've replaced it with a water and a sky experience.
+ mDayExperience.setNull();
+ mBaseDayInstance = LLEnvironment::instance().getSharedEnvironmentInstance();
+ }
+ }
+
+ void DayInjection::animate()
+ {
+
+ }
+
+ void InjectedTransition::animate()
+ {
+ mNextInstance->animate();
+
+ if (!mInjection->isOverriddenSky())
+ {
+ mSky = mStartSky->buildClone();
+ mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime);
+ mBlenderSky->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderSky.reset();
+
+ if (!mBlenderSky && !mBlenderSky)
+ mInjection->setBaseDayInstance(mNextInstance);
+ else
+ mInjection->mInjectedSky->setSource(mNextInstance->getSky());
+ });
+ }
+ else
+ {
+ mSky = mInjection->getSky();
+ mBlenderSky.reset();
+ }
+
+ if (!mInjection->isOverriddenWater())
+ {
+ mWater = mStartWater->buildClone();
+ mBlenderWater = std::make_shared<LLSettingsBlenderTimeDelta>(mWater, mStartWater, mNextInstance->getWater(), mTransitionTime);
+ mBlenderWater->setOnFinished(
+ [this](LLSettingsBlender::ptr_t blender) {
+ mBlenderWater.reset();
+
+ if (!mBlenderSky && !mBlenderWater)
+ mInjection->setBaseDayInstance(mNextInstance);
+ else
+ mInjection->mInjectedWater->setSource(mNextInstance->getWater());
+ });
+ }
+ else
+ {
+ mWater = mInjection->getWater();
+ mBlenderWater.reset();
+ }
+
+ }
+
+}
+
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
new file mode 100644
index 0000000000..7cbf2d25bb
--- /dev/null
+++ b/indra/newview/llenvironment.h
@@ -0,0 +1,477 @@
+/**
+ * @file llenvmanager.h
+ * @brief Declaration of classes managing WindLight and water settings.
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_ENVIRONMENT_H
+#define LL_ENVIRONMENT_H
+
+#include "llsingleton.h"
+#include "llmemory.h"
+#include "llsd.h"
+
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+#include "llsettingsdaycycle.h"
+
+#include "llatmosphere.h"
+
+#include <boost/signals2.hpp>
+
+//-------------------------------------------------------------------------
+class LLViewerCamera;
+class LLGLSLShader;
+class LLParcel;
+
+//-------------------------------------------------------------------------
+class LLEnvironment : public LLSingleton<LLEnvironment>
+{
+ LLSINGLETON_C11(LLEnvironment);
+ LOG_CLASS(LLEnvironment);
+
+public:
+ static const F64Seconds TRANSITION_INSTANT;
+ static const F64Seconds TRANSITION_FAST;
+ static const F64Seconds TRANSITION_DEFAULT;
+ static const F64Seconds TRANSITION_SLOW;
+ static const F64Seconds TRANSITION_ALTITUDE;
+
+ static const LLUUID KNOWN_SKY_SUNRISE;
+ static const LLUUID KNOWN_SKY_MIDDAY;
+ static const LLUUID KNOWN_SKY_SUNSET;
+ static const LLUUID KNOWN_SKY_MIDNIGHT;
+
+ static const S32 NO_TRACK;
+ static const S32 NO_VERSION;
+ static const S32 VERSION_CLEANUP;
+
+ struct EnvironmentInfo
+ {
+ EnvironmentInfo();
+
+ typedef std::shared_ptr<EnvironmentInfo> ptr_t;
+ typedef std::array<std::string, 5> namelist_t;
+
+ S32 mParcelId;
+ LLUUID mRegionId;
+ S64Seconds mDayLength;
+ S64Seconds mDayOffset;
+ size_t mDayHash;
+ LLSettingsDay::ptr_t mDayCycle;
+ std::array<F32, 4> mAltitudes;
+ bool mIsDefault;
+ LLUUID mAssetId;
+ bool mIsLegacy;
+ std::string mDayCycleName;
+ namelist_t mNameList;
+ S32 mEnvVersion;
+
+ static ptr_t extract(LLSD);
+ static ptr_t extractLegacy(LLSD);
+ };
+
+ enum EnvSelection_t
+ {
+ ENV_EDIT = 0,
+ ENV_LOCAL,
+ ENV_PUSH,
+ ENV_PARCEL,
+ ENV_REGION,
+ ENV_DEFAULT,
+ ENV_END,
+ ENV_CURRENT = -1,
+ ENV_NONE = -2
+ };
+
+ typedef boost::signals2::connection connection_t;
+
+ typedef std::pair<LLSettingsSky::ptr_t, LLSettingsWater::ptr_t> fixedEnvironment_t;
+ typedef std::function<void(S32, EnvironmentInfo::ptr_t)> environment_apply_fn;
+ typedef boost::signals2::signal<void(EnvSelection_t, S32)> env_changed_signal_t;
+ typedef env_changed_signal_t::slot_type env_changed_fn;
+ typedef std::array<F32, 4> altitude_list_t;
+ typedef std::vector<F32> altitudes_vect_t;
+
+ virtual ~LLEnvironment();
+
+ bool canEdit() const;
+ bool isExtendedEnvironmentEnabled() const;
+ bool isInventoryEnabled() const;
+ bool canAgentUpdateParcelEnvironment() const;
+ bool canAgentUpdateParcelEnvironment(LLParcel *parcel) const;
+ bool canAgentUpdateRegionEnvironment() const;
+
+ LLSettingsDay::ptr_t getCurrentDay() const { return mCurrentEnvironment->getDayCycle(); }
+ LLSettingsSky::ptr_t getCurrentSky() const;
+ LLSettingsWater::ptr_t getCurrentWater() const;
+
+ static void getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky);
+
+ void update(const LLViewerCamera * cam);
+
+ static void updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting);
+ void updateShaderUniforms(LLGLSLShader *shader);
+
+ void setSelectedEnvironment(EnvSelection_t env, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);
+ EnvSelection_t getSelectedEnvironment() const { return mSelectedEnvironment; }
+
+ bool hasEnvironment(EnvSelection_t env);
+ void setEnvironment(EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, fixedEnvironment_t fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &fixed, S32 env_version = NO_VERSION);
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); }
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version);
+ void setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, S32 env_version = NO_VERSION);
+
+ void setSharedEnvironment();
+ void clearEnvironment(EnvSelection_t env);
+
+ static void logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version = NO_VERSION);
+
+
+ LLSettingsDay::ptr_t getEnvironmentDay(EnvSelection_t env);
+ LLSettingsDay::Seconds getEnvironmentDayLength(EnvSelection_t env);
+ LLSettingsDay::Seconds getEnvironmentDayOffset(EnvSelection_t env);
+ fixedEnvironment_t getEnvironmentFixed(EnvSelection_t env, bool resolve = false);
+ LLSettingsSky::ptr_t getEnvironmentFixedSky(EnvSelection_t env, bool resolve = false) { return getEnvironmentFixed(env, resolve).first; };
+ LLSettingsWater::ptr_t getEnvironmentFixedWater(EnvSelection_t env, bool resolve = false) { return getEnvironmentFixed(env, resolve).second; };
+
+ void updateEnvironment(LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, bool forced = false);
+
+ inline LLVector2 getCloudScrollDelta() const { return mCloudScrollDelta; }
+ void pauseCloudScroll() { mCloudScrollPaused = true; }
+ void resumeCloudScroll() { mCloudScrollPaused = false; }
+ bool isCloudScrollPaused() const { return mCloudScrollPaused; }
+
+ F32 getCamHeight() const;
+ F32 getWaterHeight() const;
+ bool getIsSunUp() const;
+ bool getIsMoonUp() const;
+
+ void saveToSettings();
+ bool loadFromSettings();
+ void saveBeaconsState();
+ void revertBeaconsState();
+
+ // Returns either sun or moon direction (depending on which is up and stronger)
+ // Light direction in +x right, +z up, +y at internal coord sys
+ LLVector3 getLightDirection() const; // returns sun or moon depending on which is up
+ LLVector3 getSunDirection() const;
+ LLVector3 getMoonDirection() const;
+
+ // Returns light direction converted to CFR coord system
+ LLVector4 getLightDirectionCFR() const; // returns sun or moon depending on which is up
+ LLVector4 getSunDirectionCFR() const;
+ LLVector4 getMoonDirectionCFR() const;
+
+ // Returns light direction converted to OGL coord system
+ // and clamped above -0.1f in Y to avoid render artifacts in sky shaders
+ LLVector4 getClampedLightNorm() const; // returns sun or moon depending on which is up
+ LLVector4 getClampedSunNorm() const;
+ LLVector4 getClampedMoonNorm() const;
+
+ // Returns light direction converted to OGL coord system
+ // and rotated by last cam yaw needed by water rendering shaders
+ LLVector4 getRotatedLightNorm() const;
+
+ static LLSettingsWater::ptr_t createWaterFromLegacyPreset(const std::string filename, LLSD &messages);
+ static LLSettingsSky::ptr_t createSkyFromLegacyPreset(const std::string filename, LLSD &messages);
+ static LLSettingsDay::ptr_t createDayCycleFromLegacyPreset(const std::string filename, LLSD &messages);
+
+ // Construct a new day cycle based on the environment. Replacing either the water or the sky tracks.
+ LLSettingsDay::ptr_t createDayCycleFromEnvironment(EnvSelection_t env, LLSettingsBase::ptr_t settings);
+
+ F32 getProgress() const { return (mCurrentEnvironment) ? mCurrentEnvironment->getProgress() : -1.0f; }
+ F32 getRegionProgress() const { return (mEnvironments[ENV_REGION]) ? mEnvironments[ENV_REGION]->getProgress() : -1.0f; }
+ void adjustRegionOffset(F32 adjust); // only used on legacy regions, to better sync the viewer with other agents
+
+ //-------------------------------------------
+ connection_t setEnvironmentChanged(env_changed_fn cb) { return mSignalEnvChanged.connect(cb); }
+
+ void requestRegion(environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateRegion(const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void resetRegion(environment_apply_fn cb = environment_apply_fn());
+ void requestParcel(S32 parcel_id, environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLUUID &asset_id, std::string display_name, S32 track_num, S32 day_length, S32 day_offset, U32 flags, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 track_num, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsDay::ptr_t &pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsSky::ptr_t &psky, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void updateParcel(S32 parcel_id, const LLSettingsWater::ptr_t &pwater, S32 day_length, S32 day_offset, altitudes_vect_t altitudes = altitudes_vect_t(), environment_apply_fn cb = environment_apply_fn());
+ void resetParcel(S32 parcel_id, environment_apply_fn cb = environment_apply_fn());
+
+ void selectAgentEnvironment();
+
+ S32 calculateSkyTrackForAltitude(F64 altitude);
+
+ const altitude_list_t & getRegionAltitudes() const { return mTrackAltitudes; }
+
+ void handleEnvironmentPush(LLSD &message);
+
+ class DayInstance: public std::enable_shared_from_this<DayInstance>
+ {
+ public:
+ typedef std::shared_ptr<DayInstance> ptr_t;
+
+ static const U32 NO_ANIMATE_SKY;
+ static const U32 NO_ANIMATE_WATER;
+
+ DayInstance(EnvSelection_t env);
+ virtual ~DayInstance() { };
+
+ virtual ptr_t clone() const;
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta);
+
+ virtual void setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
+ virtual void setSky(const LLSettingsSky::ptr_t &psky);
+ virtual void setWater(const LLSettingsWater::ptr_t &pwater);
+
+ void initialize();
+ bool isInitialized();
+
+ void clear();
+
+ void setSkyTrack(S32 trackno);
+
+ LLSettingsDay::ptr_t getDayCycle() const { return mDayCycle; }
+ LLSettingsSky::ptr_t getSky() const { return mSky; }
+ LLSettingsWater::ptr_t getWater() const { return mWater; }
+ LLSettingsDay::Seconds getDayLength() const { return mDayLength; }
+ LLSettingsDay::Seconds getDayOffset() const { return mDayOffset; }
+ S32 getSkyTrack() const { return mSkyTrack; }
+
+ void setDayOffset(LLSettingsBase::Seconds offset) { mDayOffset = offset; animate(); }
+
+ virtual void animate();
+
+ void setBlenders(const LLSettingsBlender::ptr_t &skyblend, const LLSettingsBlender::ptr_t &waterblend);
+
+ EnvSelection_t getEnvironmentSelection() const { return mEnv; }
+ void setEnvironmentSelection(EnvSelection_t env) { mEnv = env; }
+
+ LLSettingsBase::TrackPosition getProgress() const;
+
+ void setFlags(U32 flag) { mAnimateFlags |= flag; }
+ void clearFlags(U32 flag) { mAnimateFlags &= ~flag; }
+ U32 getFlags() { return mAnimateFlags; }
+
+ protected:
+
+
+ LLSettingsDay::ptr_t mDayCycle;
+ LLSettingsSky::ptr_t mSky;
+ LLSettingsWater::ptr_t mWater;
+ S32 mSkyTrack;
+
+ bool mInitialized;
+
+ LLSettingsDay::Seconds mDayLength;
+ LLSettingsDay::Seconds mDayOffset;
+ S32 mLastTrackAltitude;
+
+ LLSettingsBlender::ptr_t mBlenderSky;
+ LLSettingsBlender::ptr_t mBlenderWater;
+
+ EnvSelection_t mEnv;
+
+ U32 mAnimateFlags;
+
+ LLSettingsBase::TrackPosition secondsToKeyframe(LLSettingsDay::Seconds seconds);
+ };
+
+ class DayTransition : public DayInstance
+ {
+ public:
+ DayTransition(const LLSettingsSky::ptr_t &skystart, const LLSettingsWater::ptr_t &waterstart, DayInstance::ptr_t &end, LLSettingsDay::Seconds time);
+ virtual ~DayTransition() { };
+
+ virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta) override;
+ virtual void animate() override;
+
+ protected:
+ LLSettingsSky::ptr_t mStartSky;
+ LLSettingsWater::ptr_t mStartWater;
+ DayInstance::ptr_t mNextInstance;
+ LLSettingsDay::Seconds mTransitionTime;
+ };
+
+ DayInstance::ptr_t getSelectedEnvironmentInstance();
+ DayInstance::ptr_t getSharedEnvironmentInstance();
+
+protected:
+ virtual void initSingleton() override;
+ virtual void cleanupSingleton() override;
+
+
+private:
+ LLVector4 toCFR(const LLVector3 vec) const;
+ LLVector4 toLightNorm(const LLVector3 vec) const;
+
+ typedef std::array<DayInstance::ptr_t, ENV_END> InstanceArray_t;
+
+ struct ExpEnvironmentEntry
+ {
+ typedef std::shared_ptr<ExpEnvironmentEntry> ptr_t;
+
+ S32Seconds mTime;
+ LLUUID mExperienceId;
+ LLSD mEnvironmentOverrides;
+ };
+ typedef std::deque<ExpEnvironmentEntry::ptr_t> mPushOverrides;
+
+ LLUUID mPushEnvironmentExpId;
+
+ static const F32 SUN_DELTA_YAW;
+ F32 mLastCamYaw = 0.0f;
+
+ LLVector2 mCloudScrollDelta; // cumulative cloud delta
+ bool mCloudScrollPaused;
+
+ InstanceArray_t mEnvironments;
+
+ EnvSelection_t mSelectedEnvironment;
+ DayInstance::ptr_t mCurrentEnvironment;
+
+ LLSettingsSky::ptr_t mSelectedSky;
+ LLSettingsWater::ptr_t mSelectedWater;
+ LLSettingsDay::ptr_t mSelectedDay;
+
+ LLSettingsBlender::ptr_t mBlenderSky;
+ LLSettingsBlender::ptr_t mBlenderWater;
+
+ env_changed_signal_t mSignalEnvChanged;
+
+ S32 mCurrentTrack;
+ altitude_list_t mTrackAltitudes;
+
+ LLSD mSkyOverrides;
+ LLSD mWaterOverrides;
+ typedef std::map<std::string, LLUUID> experience_overrides_t;
+ experience_overrides_t mExperienceOverrides;
+
+ DayInstance::ptr_t getEnvironmentInstance(EnvSelection_t env, bool create = false);
+
+ void updateCloudScroll();
+
+ void onRegionChange();
+ void onParcelChange();
+
+ bool mShowSunBeacon;
+ bool mShowMoonBeacon;
+ S32 mEditorCounter;
+
+ struct UpdateInfo
+ {
+ typedef std::shared_ptr<UpdateInfo> ptr_t;
+
+ UpdateInfo(LLSettingsDay::ptr_t pday, S32 day_length, S32 day_offset, altitudes_vect_t altitudes):
+ mDayp(pday),
+ mSettingsAsset(),
+ mDayLength(day_length),
+ mDayOffset(day_offset),
+ mAltitudes(altitudes),
+ mDayName(),
+ mFlags(0)
+ {
+ if (mDayp)
+ {
+ mDayName = mDayp->getName();
+ mFlags = mDayp->getFlags();
+ }
+ }
+
+ UpdateInfo(LLUUID settings_asset, std::string name, S32 day_length, S32 day_offset, altitudes_vect_t altitudes, U32 flags) :
+ mDayp(),
+ mSettingsAsset(settings_asset),
+ mDayLength(day_length),
+ mDayOffset(day_offset),
+ mAltitudes(altitudes),
+ mDayName(name),
+ mFlags(flags)
+ {}
+
+ LLSettingsDay::ptr_t mDayp;
+ LLUUID mSettingsAsset;
+ S32 mDayLength;
+ S32 mDayOffset;
+ altitudes_vect_t mAltitudes;
+ std::string mDayName;
+ U32 mFlags;
+ };
+
+ void coroRequestEnvironment(S32 parcel_id, environment_apply_fn apply);
+ void coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInfo::ptr_t updates, environment_apply_fn apply);
+ void coroResetEnvironment(S32 parcel_id, S32 track_no, environment_apply_fn apply);
+
+ void recordEnvironment(S32 parcel_id, EnvironmentInfo::ptr_t environment, LLSettingsBase::Seconds transition);
+
+ void onAgentPositionHasChanged(const LLVector3 &localpos);
+
+ void onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
+ void onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);
+
+ void handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition);
+ void handleEnvironmentPushFull(LLUUID experience_id, LLSD &message, F32 transition);
+ void handleEnvironmentPushPartial(LLUUID experience_id, LLSD &message, F32 transition);
+
+ void clearExperienceEnvironment(LLUUID experience_id, LLSettingsBase::Seconds transition_time);
+ void setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time);
+ void setExperienceEnvironment(LLUUID experience_id, LLSD environment, F32 transition_time);
+ void onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettingsBase::ptr_t setting, F32 transition_time, S32 status);
+
+ void listenExperiencePump(const LLSD &message);
+ void loadSkyWaterFromSettings(const LLSD &env_data, bool &valid, bool &assets_present); // for use in loadFromSettings()
+
+};
+
+class LLTrackBlenderLoopingManual : public LLSettingsBlender
+{
+public:
+ LLTrackBlenderLoopingManual(const LLSettingsBase::ptr_t &target, const LLSettingsDay::ptr_t &day, S32 trackno);
+
+ F64 setPosition(const LLSettingsBase::TrackPosition& position);
+ virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) override;
+ S32 getTrack() const { return mTrackNo; }
+
+ typedef std::shared_ptr<LLTrackBlenderLoopingManual> ptr_t;
+protected:
+ LLSettingsDay::TrackBound_t getBoundingEntries(F64 position);
+ F64 getSpanLength(const LLSettingsDay::TrackBound_t &bounds) const;
+
+private:
+ LLSettingsDay::ptr_t mDay;
+ S32 mTrackNo;
+ F64 mPosition;
+
+ LLSettingsDay::CycleTrack_t::iterator mEndMarker;
+};
+
+#endif // LL_ENVIRONMENT_H
+
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
deleted file mode 100644
index fa1c3b983e..0000000000
--- a/indra/newview/llenvmanager.cpp
+++ /dev/null
@@ -1,721 +0,0 @@
-/**
- * @file llenvmanager.cpp
- * @brief Implementation of classes managing WindLight and water settings.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llenvmanager.h"
-
-#include "llagent.h"
-#include "lldaycyclemanager.h"
-#include "llviewercontrol.h" // for gSavedSettings
-#include "llviewerregion.h"
-#include "llwaterparammanager.h"
-#include "llwlhandlers.h"
-#include "llwlparammanager.h"
-#include "lltrans.h"
-
-std::string LLWLParamKey::toString() const
-{
- switch (scope)
- {
- case SCOPE_LOCAL:
- return name + std::string(" (") + LLTrans::getString("Local") + std::string(")");
- break;
- case SCOPE_REGION:
- return name + std::string(" (") + LLTrans::getString("Region") + std::string(")");
- break;
- default:
- return name + " (?)";
- }
-}
-
-std::string LLEnvPrefs::getWaterPresetName() const
-{
- if (mWaterPresetName.empty())
- {
- LL_WARNS() << "Water preset name is empty" << LL_ENDL;
- }
-
- return mWaterPresetName;
-}
-
-std::string LLEnvPrefs::getSkyPresetName() const
-{
- if (mSkyPresetName.empty())
- {
- LL_WARNS() << "Sky preset name is empty" << LL_ENDL;
- }
-
- return mSkyPresetName;
-}
-
-std::string LLEnvPrefs::getDayCycleName() const
-{
- if (mDayCycleName.empty())
- {
- LL_WARNS() << "Day cycle name is empty" << LL_ENDL;
- }
-
- return mDayCycleName;
-}
-
-void LLEnvPrefs::setUseRegionSettings(bool val)
-{
- mUseRegionSettings = val;
-}
-
-void LLEnvPrefs::setUseWaterPreset(const std::string& name)
-{
- mUseRegionSettings = false;
- mWaterPresetName = name;
-}
-
-void LLEnvPrefs::setUseSkyPreset(const std::string& name)
-{
- mUseRegionSettings = false;
- mUseDayCycle = false;
- mSkyPresetName = name;
-}
-
-void LLEnvPrefs::setUseDayCycle(const std::string& name)
-{
- mUseRegionSettings = false;
- mUseDayCycle = true;
- mDayCycleName = name;
-}
-
-//=============================================================================
-LLEnvManagerNew::LLEnvManagerNew():
- mInterpNextChangeMessage(true),
- mCurRegionUUID(LLUUID::null),
- mLastReceivedID(LLUUID::null)
-{
-
- // Set default environment settings.
- mUserPrefs.mUseRegionSettings = true;
- mUserPrefs.mUseDayCycle = true;
- mUserPrefs.mWaterPresetName = "Default";
- mUserPrefs.mSkyPresetName = "Default";
- mUserPrefs.mDayCycleName = "Default";
-
- LL_DEBUGS("Windlight")<<LL_ENDL;
- gAgent.addRegionChangedCallback(boost::bind(&LLEnvManagerNew::onRegionChange, this));
-}
-
-bool LLEnvManagerNew::getUseRegionSettings() const
-{
- return mUserPrefs.getUseRegionSettings();
-}
-
-bool LLEnvManagerNew::getUseDayCycle() const
-{
- return mUserPrefs.getUseDayCycle();
-}
-
-bool LLEnvManagerNew::getUseFixedSky() const
-{
- return mUserPrefs.getUseFixedSky();
-}
-
-std::string LLEnvManagerNew::getWaterPresetName() const
-{
- return mUserPrefs.getWaterPresetName();
-}
-
-std::string LLEnvManagerNew::getSkyPresetName() const
-{
- return mUserPrefs.getSkyPresetName();
-}
-
-std::string LLEnvManagerNew::getDayCycleName() const
-{
- return mUserPrefs.getDayCycleName();
-}
-
-const LLEnvironmentSettings& LLEnvManagerNew::getRegionSettings() const
-{
- return !mNewRegionPrefs.isEmpty() ? mNewRegionPrefs : mCachedRegionPrefs;
-}
-
-void LLEnvManagerNew::setRegionSettings(const LLEnvironmentSettings& new_settings)
-{
- // Set region settings override that will be used locally
- // until user either uploads the changes or goes to another region.
- mNewRegionPrefs = new_settings;
-}
-
-bool LLEnvManagerNew::usePrefs()
-{
- LL_DEBUGS("Windlight") << "Displaying preferred environment" << LL_ENDL;
- updateManagersFromPrefs(false);
- return true;
-}
-
-bool LLEnvManagerNew::useDefaults()
-{
- bool rslt;
-
- rslt = useDefaultWater();
- rslt &= useDefaultSky();
-
- return rslt;
-}
-
-bool LLEnvManagerNew::useRegionSettings()
-{
- bool rslt;
-
- rslt = useRegionSky();
- rslt &= useRegionWater();
-
- return rslt;
-}
-
-bool LLEnvManagerNew::useWaterPreset(const std::string& name)
-{
- LL_DEBUGS("Windlight") << "Displaying water preset " << name << LL_ENDL;
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- bool rslt = water_mgr.getParamSet(name, water_mgr.mCurParams);
- llassert(rslt == true);
- return rslt;
-}
-
-bool LLEnvManagerNew::useWaterParams(const LLSD& params)
-{
- LL_DEBUGS("Windlight") << "Displaying water params" << LL_ENDL;
- LLWaterParamManager::instance().mCurParams.setAll(params);
- return true;
-}
-
-bool LLEnvManagerNew::useSkyPreset(const std::string& name)
-{
- LLWLParamManager& sky_mgr = LLWLParamManager::instance();
- LLWLParamSet param_set;
-
- if (!sky_mgr.getParamSet(LLWLParamKey(name, LLEnvKey::SCOPE_LOCAL), param_set))
- {
- LL_WARNS() << "No sky preset named " << name << LL_ENDL;
- return false;
- }
-
- LL_DEBUGS("Windlight") << "Displaying sky preset " << name << LL_ENDL;
- sky_mgr.applySkyParams(param_set.getAll());
- return true;
-}
-
-bool LLEnvManagerNew::useSkyParams(const LLSD& params)
-{
- LL_DEBUGS("Windlight") << "Displaying sky params" << LL_ENDL;
- LLWLParamManager::instance().applySkyParams(params);
- return true;
-}
-
-bool LLEnvManagerNew::useDayCycle(const std::string& name, LLEnvKey::EScope scope)
-{
- LLSD params;
-
- if (scope == LLEnvKey::SCOPE_REGION)
- {
- LL_DEBUGS("Windlight") << "Displaying region day cycle " << name << LL_ENDL;
- params = getRegionSettings().getWLDayCycle();
- }
- else
- {
- LL_DEBUGS("Windlight") << "Displaying local day cycle " << name << LL_ENDL;
-
- if (!LLDayCycleManager::instance().getPreset(name, params))
- {
- LL_WARNS() << "No day cycle named " << name << LL_ENDL;
- return false;
- }
- }
-
- bool rslt = LLWLParamManager::instance().applyDayCycleParams(params, scope);
- llassert(rslt == true);
- return rslt;
-}
-
-bool LLEnvManagerNew::useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time /* = 0.5*/)
-{
- LL_DEBUGS("Windlight") << "Displaying day cycle params" << LL_ENDL;
- return LLWLParamManager::instance().applyDayCycleParams(params, scope);
-}
-
-void LLEnvManagerNew::setUseRegionSettings(bool val)
-{
- mUserPrefs.setUseRegionSettings(val);
- saveUserPrefs();
- updateManagersFromPrefs(false);
-}
-
-void LLEnvManagerNew::setUseWaterPreset(const std::string& name)
-{
- // *TODO: make sure the preset exists.
- if (name.empty())
- {
- LL_WARNS() << "Empty water preset name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseWaterPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(false);
-}
-
-void LLEnvManagerNew::setUseSkyPreset(const std::string& name)
-{
- // *TODO: make sure the preset exists.
- if (name.empty())
- {
- LL_WARNS() << "Empty sky preset name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseSkyPreset(name);
- saveUserPrefs();
- updateManagersFromPrefs(false);
-}
-
-void LLEnvManagerNew::setUseDayCycle(const std::string& name)
-{
- if (!LLDayCycleManager::instance().presetExists(name))
- {
- LL_WARNS() << "Invalid day cycle name passed" << LL_ENDL;
- return;
- }
-
- mUserPrefs.setUseDayCycle(name);
- saveUserPrefs();
- updateManagersFromPrefs(false);
-}
-
-void LLEnvManagerNew::loadUserPrefs()
-{
- // operate on members directly to avoid side effects
- mUserPrefs.mWaterPresetName = gSavedSettings.getString("WaterPresetName");
- mUserPrefs.mSkyPresetName = gSavedSettings.getString("SkyPresetName");
- mUserPrefs.mDayCycleName = gSavedSettings.getString("DayCycleName");
-
- bool use_region_settings = gSavedSettings.getBOOL("EnvironmentPersistAcrossLogin") ? gSavedSettings.getBOOL("UseEnvironmentFromRegion") : true;
- mUserPrefs.mUseRegionSettings = use_region_settings;
- mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle");
-
- if (mUserPrefs.mUseRegionSettings)
- {
- requestRegionSettings();
- }
-}
-
-void LLEnvManagerNew::saveUserPrefs()
-{
- gSavedSettings.setString("WaterPresetName", getWaterPresetName());
- gSavedSettings.setString("SkyPresetName", getSkyPresetName());
- gSavedSettings.setString("DayCycleName", getDayCycleName());
-
- gSavedSettings.setBOOL("UseEnvironmentFromRegion", getUseRegionSettings());
- gSavedSettings.setBOOL("UseDayCycle", getUseDayCycle());
-
- mUsePrefsChangeSignal();
-}
-
-void LLEnvManagerNew::setUserPrefs(
- const std::string& water_preset,
- const std::string& sky_preset,
- const std::string& day_cycle_preset,
- bool use_fixed_sky,
- bool use_region_settings)
-{
- // operate on members directly to avoid side effects
- mUserPrefs.mWaterPresetName = water_preset;
- mUserPrefs.mSkyPresetName = sky_preset;
- mUserPrefs.mDayCycleName = day_cycle_preset;
-
- mUserPrefs.mUseRegionSettings = use_region_settings;
- mUserPrefs.mUseDayCycle = !use_fixed_sky;
-
- saveUserPrefs();
- updateManagersFromPrefs(false);
-}
-
-void LLEnvManagerNew::dumpUserPrefs()
-{
- LL_DEBUGS("Windlight") << "WaterPresetName: " << gSavedSettings.getString("WaterPresetName") << LL_ENDL;
- LL_DEBUGS("Windlight") << "SkyPresetName: " << gSavedSettings.getString("SkyPresetName") << LL_ENDL;
- LL_DEBUGS("Windlight") << "DayCycleName: " << gSavedSettings.getString("DayCycleName") << LL_ENDL;
-
- LL_DEBUGS("Windlight") << "UseEnvironmentFromRegion: " << gSavedSettings.getBOOL("UseEnvironmentFromRegion") << LL_ENDL;
- LL_DEBUGS("Windlight") << "UseDayCycle: " << gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL;
-}
-
-void LLEnvManagerNew::dumpPresets()
-{
- const LLEnvironmentSettings& region_settings = getRegionSettings();
- std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : "Unknown region";
-
- // Dump water presets.
- LL_DEBUGS("Windlight") << "Waters:" << LL_ENDL;
- if (region_settings.getWaterParams().size() != 0)
- {
- LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
- }
- LLWaterParamManager::preset_name_list_t water_presets;
- LLWaterParamManager::instance().getPresetNames(water_presets);
- for (LLWaterParamManager::preset_name_list_t::const_iterator it = water_presets.begin(); it != water_presets.end(); ++it)
- {
- LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
- }
-
- // Dump sky presets.
- LL_DEBUGS("Windlight") << "Skies:" << LL_ENDL;
- LLWLParamManager::preset_key_list_t sky_preset_keys;
- LLWLParamManager::instance().getPresetKeys(sky_preset_keys);
- for (LLWLParamManager::preset_key_list_t::const_iterator it = sky_preset_keys.begin(); it != sky_preset_keys.end(); ++it)
- {
- std::string preset_name = it->name;
- std::string item_title;
-
- if (it->scope == LLEnvKey::SCOPE_LOCAL) // local preset
- {
- item_title = preset_name;
- }
- else // region preset
- {
- item_title = preset_name + " (" + region_name + ")";
- }
- LL_DEBUGS("Windlight") << " - " << item_title << LL_ENDL;
- }
-
- // Dump day cycles.
- LL_DEBUGS("Windlight") << "Days:" << LL_ENDL;
- const LLSD& cur_region_dc = region_settings.getWLDayCycle();
- if (cur_region_dc.size() != 0)
- {
- LL_DEBUGS("Windlight") << " - " << region_name << LL_ENDL;
- }
- LLDayCycleManager::preset_name_list_t days;
- LLDayCycleManager::instance().getPresetNames(days);
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = days.begin(); it != days.end(); ++it)
- {
- LL_DEBUGS("Windlight") << " - " << *it << LL_ENDL;
- }
-}
-
-void LLEnvManagerNew::requestRegionSettings()
-{
- LL_DEBUGS("Windlight") << LL_ENDL;
- LLEnvironmentRequest::initiate();
-}
-
-bool LLEnvManagerNew::sendRegionSettings(const LLEnvironmentSettings& new_settings)
-{
- LLSD metadata;
-
- metadata["regionID"] = gAgent.getRegion()->getRegionID();
- // add last received update ID to outbound message so simulator can handle concurrent updates
- metadata["messageID"] = mLastReceivedID;
-
- return LLEnvironmentApply::initiateRequest(new_settings.makePacket(metadata));
-}
-
-boost::signals2::connection LLEnvManagerNew::setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb)
-{
- return mUsePrefsChangeSignal.connect(cb);
-}
-
-boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb)
-{
- return mRegionSettingsChangeSignal.connect(cb);
-}
-
-boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb)
-{
- return mRegionSettingsAppliedSignal.connect(cb);
-}
-
-// static
-bool LLEnvManagerNew::canEditRegionSettings()
-{
- LLViewerRegion* region = gAgent.getRegion();
- BOOL owner_or_god = gAgent.isGodlike() || (region && region->getOwner() == gAgent.getID());
- BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager());
-
- LL_DEBUGS("Windlight") << "Can edit region settings: " << (bool) owner_or_god_or_manager << LL_ENDL;
- return owner_or_god_or_manager;
-}
-
-// static
-const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope)
-{
- switch(scope)
- {
- case LLEnvKey::SCOPE_LOCAL:
- return LLTrans::getString("LocalSettings");
- case LLEnvKey::SCOPE_REGION:
- return LLTrans::getString("RegionSettings");
- default:
- return " (?)";
- }
-}
-
-void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
-{
- // If the message was valid, grab the UUID from it and save it for next outbound update message.
- mLastReceivedID = content[0]["messageID"].asUUID();
-
- // Refresh cached region settings.
- LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL;
- F32 sun_hour = 0; // *TODO
- LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour);
- mCachedRegionPrefs = new_settings;
-
- // Load region sky presets.
- LLWLParamManager::instance().refreshRegionPresets(getRegionSettings().getSkyMap());
-
- // If using server settings, update managers.
- if (getUseRegionSettings())
- {
- updateManagersFromPrefs(mInterpNextChangeMessage);
- }
-
- // Let interested parties know about the region settings update.
- mRegionSettingsChangeSignal();
-
- // reset
- mInterpNextChangeMessage = false;
-}
-
-void LLEnvManagerNew::onRegionSettingsApplyResponse(bool ok)
-{
- LL_DEBUGS("Windlight") << "Applying region settings " << (ok ? "succeeded" : "failed") << LL_ENDL;
-
- // Clear locally modified region settings because they have just been uploaded.
- mNewRegionPrefs.clear();
-
- mRegionSettingsAppliedSignal(ok);
-}
-
-//-- private methods ----------------------------------------------------------
-
-// virtual
-void LLEnvManagerNew::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Initializing LLEnvManagerNew" << LL_ENDL;
-
- loadUserPrefs();
-
- // preferences loaded, can set params
- std::string preferred_day = getDayCycleName();
- if (!useDayCycle(preferred_day, LLEnvKey::SCOPE_LOCAL))
- {
- LL_WARNS() << "No day cycle named " << preferred_day << ", reverting LLWLParamManager to defaults" << LL_ENDL;
- LLWLParamManager::instance().setDefaultDay();
- }
-
- std::string sky = getSkyPresetName();
- if (!useSkyPreset(sky))
- {
- LL_WARNS() << "No sky preset named " << sky << ", falling back to defaults" << LL_ENDL;
- LLWLParamManager::instance().setDefaultSky();
-
- // *TODO: Fix user preferences accordingly.
- }
-
- LLWLParamManager::instance().resetAnimator(0.5 /*noon*/, getUseDayCycle());
-}
-
-void LLEnvManagerNew::updateSkyFromPrefs()
-{
- bool success = true;
-
- // Sync sky with user prefs.
- if (getUseRegionSettings()) // apply region-wide settings
- {
- success = useRegionSky();
- }
- else // apply user-specified settings
- {
- if (getUseDayCycle())
- {
- success = useDayCycle(getDayCycleName(), LLEnvKey::SCOPE_LOCAL);
- }
- else
- {
- success = useSkyPreset(getSkyPresetName());
- }
- }
-
- // If something went wrong, fall back to defaults.
- if (!success)
- {
- // *TODO: fix user prefs
- useDefaultSky();
- }
-}
-
-void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate)
-{
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- LLSD target_water_params;
-
- // Determine new water settings based on user prefs.
-
- {
- // Fall back to default water.
- LLWaterParamSet default_water;
- water_mgr.getParamSet("Default", default_water);
- target_water_params = default_water.getAll();
- }
-
- if (getUseRegionSettings())
- {
- // *TODO: make sure whether region settings belong to the current region?
- const LLSD& region_water_params = getRegionSettings().getWaterParams();
- if (region_water_params.size() != 0) // region has no water settings
- {
- LL_DEBUGS("Windlight") << "Applying region water" << LL_ENDL;
- target_water_params = region_water_params;
- }
- else
- {
- LL_DEBUGS("Windlight") << "Applying default water" << LL_ENDL;
- }
- }
- else
- {
- std::string water = getWaterPresetName();
- LL_DEBUGS("Windlight") << "Applying water preset [" << water << "]" << LL_ENDL;
- LLWaterParamSet params;
- if (!water_mgr.getParamSet(water, params))
- {
- LL_WARNS() << "No water preset named " << water << ", falling back to defaults" << LL_ENDL;
- water_mgr.getParamSet("Default", params);
-
- // *TODO: Fix user preferences accordingly.
- }
- target_water_params = params.getAll();
- }
-
- // Sync water with user prefs.
- water_mgr.applyParams(target_water_params, interpolate);
-}
-
-void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate)
-{
- LL_DEBUGS("Windlight")<<LL_ENDL;
- // Apply water settings.
- updateWaterFromPrefs(interpolate);
-
- // Apply sky settings.
- updateSkyFromPrefs();
-}
-
-bool LLEnvManagerNew::useRegionSky()
-{
- const LLEnvironmentSettings& region_settings = getRegionSettings();
-
- // If region is set to defaults,
- if (region_settings.getSkyMap().size() == 0)
- {
- // well... apply the default sky settings.
- useDefaultSky();
- return true;
- }
-
- // Otherwise apply region day cycle/skies.
- LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
-
- // *TODO: Support fixed sky from region. Just do sky reset for now.
- if (region_settings.getSkyMap().size() == 1)
- {
- // Region is set to fixed sky. Reset.
- useSkyParams(region_settings.getSkyMap().beginMap()->second);
- }
- return useDayCycleParams(
- region_settings.getWLDayCycle(),
- LLEnvKey::SCOPE_REGION,
- region_settings.getDayTime());
-}
-
-bool LLEnvManagerNew::useRegionWater()
-{
- const LLEnvironmentSettings& region_settings = getRegionSettings();
- const LLSD& region_water = region_settings.getWaterParams();
-
- // If region is set to defaults,
- if (region_water.size() == 0)
- {
- // well... apply the default water settings.
- return useDefaultWater();
- }
-
- // Otherwise apply region water.
- LL_DEBUGS("Windlight") << "Applying region sky" << LL_ENDL;
- return useWaterParams(region_water);
-}
-
-bool LLEnvManagerNew::useDefaultSky()
-{
- return useDayCycle("Default", LLEnvKey::SCOPE_LOCAL);
-}
-
-bool LLEnvManagerNew::useDefaultWater()
-{
- return useWaterPreset("Default");
-}
-
-
-void LLEnvManagerNew::onRegionChange()
-{
- // Avoid duplicating region setting requests
- // by checking whether the region is actually changing.
- LLViewerRegion* regionp = gAgent.getRegion();
- LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null;
- if (region_uuid != mCurRegionUUID)
- {
- // Clear locally modified region settings.
- mNewRegionPrefs.clear();
-
- // *TODO: clear environment settings of the previous region?
-
- // Request environment settings of the new region.
- mCurRegionUUID = region_uuid;
- // for region crossings, interpolate the change; for teleports, don't
- mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE);
- LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported")
- << " to new region: " << region_uuid
- << LL_ENDL;
- requestRegionSettings();
- }
- else
- {
- LL_DEBUGS("Windlight") << "disregarding region change; interp: "
- << (mInterpNextChangeMessage ? "true" : "false")
- << " regionp: " << regionp
- << " old: " << mCurRegionUUID
- << " new: " << region_uuid
- << LL_ENDL;
- }
-}
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
deleted file mode 100644
index 54bbf85e86..0000000000
--- a/indra/newview/llenvmanager.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * @file llenvmanager.h
- * @brief Declaration of classes managing WindLight and water settings.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLENVMANAGER_H
-#define LL_LLENVMANAGER_H
-
-#include "llmemory.h"
-#include "llsd.h"
-
-class LLWLParamManager;
-class LLWaterParamManager;
-class LLWLAnimator;
-
-// generic key
-struct LLEnvKey
-{
-public:
- // Note: enum ordering is important; for example, a region-level floater (1) will see local and region (all values that are <=)
- typedef enum e_scope
- {
- SCOPE_LOCAL, // 0
- SCOPE_REGION//, // 1
- // SCOPE_ESTATE, // 2
- // etc.
- } EScope;
-};
-
-struct LLWLParamKey : LLEnvKey
-{
-public:
- // scope and source of a param set (WL sky preset)
- std::string name;
- EScope scope;
-
- // for conversion from LLSD
- static const int NAME_IDX = 0;
- static const int SCOPE_IDX = 1;
-
- inline LLWLParamKey(const std::string& n, EScope s)
- : name(n), scope(s)
- {
- }
-
- inline LLWLParamKey(LLSD llsd)
- : name(llsd[NAME_IDX].asString()), scope(EScope(llsd[SCOPE_IDX].asInteger()))
- {
- }
-
- inline LLWLParamKey() // NOT really valid, just so std::maps can return a default of some sort
- : name(""), scope(SCOPE_LOCAL)
- {
- }
-
- inline LLWLParamKey(std::string& stringVal)
- {
- size_t len = stringVal.length();
- if (len > 0)
- {
- name = stringVal.substr(0, len - 1);
- scope = (EScope) atoi(stringVal.substr(len - 1, len).c_str());
- }
- }
-
- inline std::string toStringVal() const
- {
- std::stringstream str;
- str << name << scope;
- return str.str();
- }
-
- inline LLSD toLLSD() const
- {
- LLSD llsd = LLSD::emptyArray();
- llsd.append(LLSD(name));
- llsd.append(LLSD(scope));
- return llsd;
- }
-
- inline void fromLLSD(const LLSD& llsd)
- {
- name = llsd[NAME_IDX].asString();
- scope = EScope(llsd[SCOPE_IDX].asInteger());
- }
-
- inline bool operator <(const LLWLParamKey other) const
- {
- if (name < other.name)
- {
- return true;
- }
- else if (name > other.name)
- {
- return false;
- }
- else
- {
- return scope < other.scope;
- }
- }
-
- inline bool operator ==(const LLWLParamKey other) const
- {
- return (name == other.name) && (scope == other.scope);
- }
-
- std::string toString() const;
-};
-
-class LLEnvironmentSettings
-{
-public:
- LLEnvironmentSettings() :
- mWLDayCycle(LLSD::emptyMap()),
- mSkyMap(LLSD::emptyMap()),
- mWaterParams(LLSD::emptyMap()),
- mDayTime(0.f)
- {}
- LLEnvironmentSettings(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime) :
- mWLDayCycle(dayCycle),
- mSkyMap(skyMap),
- mWaterParams(waterParams),
- mDayTime(dayTime)
- {}
- ~LLEnvironmentSettings() {}
-
- void saveParams(const LLSD& dayCycle, const LLSD& skyMap, const LLSD& waterParams, F64 dayTime)
- {
- mWLDayCycle = dayCycle;
- mSkyMap = skyMap;
- mWaterParams = waterParams;
- mDayTime = dayTime;
- }
-
- const LLSD& getWLDayCycle() const
- {
- return mWLDayCycle;
- }
-
- const LLSD& getWaterParams() const
- {
- return mWaterParams;
- }
-
- const LLSD& getSkyMap() const
- {
- return mSkyMap;
- }
-
- F64 getDayTime() const
- {
- return mDayTime;
- }
-
- bool isEmpty() const
- {
- return mWLDayCycle.size() == 0;
- }
-
- void clear()
- {
- *this = LLEnvironmentSettings();
- }
-
- LLSD makePacket(const LLSD& metadata) const
- {
- LLSD full_packet = LLSD::emptyArray();
-
- // 0: metadata
- full_packet.append(metadata);
-
- // 1: day cycle
- full_packet.append(mWLDayCycle);
-
- // 2: map of sky setting names to sky settings (as LLSD)
- full_packet.append(mSkyMap);
-
- // 3: water params
- full_packet.append(mWaterParams);
-
- return full_packet;
- }
-
-private:
- LLSD mWLDayCycle, mWaterParams, mSkyMap;
- F64 mDayTime;
-};
-
-/**
- * User environment preferences.
- */
-class LLEnvPrefs
-{
-public:
- LLEnvPrefs() : mUseRegionSettings(true), mUseDayCycle(true) {}
-
- bool getUseRegionSettings() const { return mUseRegionSettings; }
- bool getUseDayCycle() const { return mUseDayCycle; }
- bool getUseFixedSky() const { return !getUseDayCycle(); }
-
- std::string getWaterPresetName() const;
- std::string getSkyPresetName() const;
- std::string getDayCycleName() const;
-
- void setUseRegionSettings(bool val);
- void setUseWaterPreset(const std::string& name);
- void setUseSkyPreset(const std::string& name);
- void setUseDayCycle(const std::string& name);
-
- bool mUseRegionSettings;
- bool mUseDayCycle;
- std::string mWaterPresetName;
- std::string mSkyPresetName;
- std::string mDayCycleName;
-};
-
-/**
- * Setting:
- * 1. Use region settings.
- * 2. Use my setting: <water preset> + <fixed_sky>|<day_cycle>
- */
-class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
-{
- LLSINGLETON(LLEnvManagerNew);
- LOG_CLASS(LLEnvManagerNew);
-public:
- typedef boost::signals2::signal<void()> prefs_change_signal_t;
- typedef boost::signals2::signal<void()> region_settings_change_signal_t;
- typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t;
-
- // getters to access user env. preferences
- bool getUseRegionSettings() const;
- bool getUseDayCycle() const;
- bool getUseFixedSky() const;
- std::string getWaterPresetName() const;
- std::string getSkyPresetName() const;
- std::string getDayCycleName() const;
-
- /// @return cached env. settings of the current region.
- const LLEnvironmentSettings& getRegionSettings() const;
-
- /**
- * Set new region settings without uploading them to the region.
- *
- * The override will be reset when the changes are applied to the region (=uploaded)
- * or user teleports to another region.
- */
- void setRegionSettings(const LLEnvironmentSettings& new_settings);
-
- // Change environment w/o changing user preferences.
- bool usePrefs();
- bool useDefaults();
- bool useRegionSettings();
- bool useWaterPreset(const std::string& name);
- bool useWaterParams(const LLSD& params);
- bool useSkyPreset(const std::string& name);
- bool useSkyParams(const LLSD& params);
- bool useDayCycle(const std::string& name, LLEnvKey::EScope scope);
- bool useDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5);
-
- // setters for user env. preferences
- void setUseRegionSettings(bool val);
- void setUseWaterPreset(const std::string& name);
- void setUseSkyPreset(const std::string& name);
- void setUseDayCycle(const std::string& name);
- void setUserPrefs(
- const std::string& water_preset,
- const std::string& sky_preset,
- const std::string& day_cycle_preset,
- bool use_fixed_sky,
- bool use_region_settings);
-
- // debugging methods
- void dumpUserPrefs();
- void dumpPresets();
-
- // Misc.
- void requestRegionSettings();
- bool sendRegionSettings(const LLEnvironmentSettings& new_settings);
- boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb);
- boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb);
- boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb);
-
- static bool canEditRegionSettings(); /// @return true if we have access to editing region environment
- static const std::string getScopeString(LLEnvKey::EScope scope);
-
- // Public callbacks.
- void onRegionSettingsResponse(const LLSD& content);
- void onRegionSettingsApplyResponse(bool ok);
-
-private:
- /*virtual*/ void initSingleton();
-
- void loadUserPrefs();
- void saveUserPrefs();
-
- void updateSkyFromPrefs();
- void updateWaterFromPrefs(bool interpolate);
- void updateManagersFromPrefs(bool interpolate);
-
- bool useRegionSky();
- bool useRegionWater();
-
- bool useDefaultSky();
- bool useDefaultWater();
-
- void onRegionChange();
-
- /// Emitted when user environment preferences change.
- prefs_change_signal_t mUsePrefsChangeSignal;
-
- /// Emitted when region environment settings update comes.
- region_settings_change_signal_t mRegionSettingsChangeSignal;
-
- /// Emitted when agent region changes. Move to LLAgent?
- region_settings_applied_signal_t mRegionSettingsAppliedSignal;
-
- LLEnvPrefs mUserPrefs; /// User environment preferences.
- LLEnvironmentSettings mCachedRegionPrefs; /// Cached region environment settings.
- LLEnvironmentSettings mNewRegionPrefs; /// Not-yet-uploaded modified region env. settings.
- bool mInterpNextChangeMessage; /// Interpolate env. settings on next region change.
- LLUUID mCurRegionUUID; /// To avoid duplicated region env. settings requests.
- LLUUID mLastReceivedID; /// Id of last received region env. settings.
-};
-
-#endif // LL_LLENVMANAGER_H
-
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 95d40be913..4fdb860592 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -73,6 +73,7 @@ bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS
bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); }
bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
+bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); }
void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); }
void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); }
@@ -81,6 +82,7 @@ void LLEstateInfoModel::setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY
void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); }
void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); }
void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); }
+void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); }
void LLEstateInfoModel::update(const strings_t& strings)
{
@@ -222,6 +224,7 @@ std::string LLEstateInfoModel::getInfoDump()
dump["deny_age_unverified" ] = getDenyAgeUnverified();
dump["allow_voice_chat" ] = getAllowVoiceChat();
dump["override_public_access"] = getAllowAccessOverride();
+ dump["override_environment"] = getAllowEnvironmentOverride();
std::stringstream dump_str;
dump_str << dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 0082b5b1f4..d6f00c573c 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -56,6 +56,7 @@ public:
bool getDenyAgeUnverified() const;
bool getAllowVoiceChat() const;
bool getAllowAccessOverride() const;
+ bool getAllowEnvironmentOverride() const;
const std::string& getName() const { return mName; }
const LLUUID& getOwnerID() const { return mOwnerID; }
@@ -70,6 +71,7 @@ public:
void setDenyAgeUnverified(bool val);
void setAllowVoiceChat(bool val);
void setAllowAccessOverride(bool val);
+ void setAllowEnvironmentOverride(bool val);
void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 5e0f3ab7f9..4b5fd8a758 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -106,6 +106,7 @@ namespace Details
LLSD message;
message["sender"] = mSenderIp;
message["body"] = content["body"];
+
LLMessageSystem::dispatch(msg_name, message);
}
@@ -165,6 +166,14 @@ namespace Details
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
// << LLSDXMLStreamer(result) << LL_ENDL;
+ if (gDisconnected)
+ {
+ // Lost connection or disconnected during quit, don't process sim/region update
+ // messages, they might populate some cleaned up classes (LLWorld, region and object list)
+ LL_INFOS("LLEventPollImpl") << "Dropping event messages" << LL_ENDL;
+ break;
+ }
+
LLSD httpResults = result["http_result"];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -209,7 +218,7 @@ namespace Details
llcoro::suspendUntilTimeout(waitToRetry);
- if (mDone)
+ if (mDone || gDisconnected)
break;
LL_INFOS("LLEventPollImpl") << "<" << counter << "> About to retry request." << LL_ENDL;
continue;
@@ -241,7 +250,7 @@ namespace Details
!result.get("events") ||
!result.get("id"))
{
- LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << LLSDXMLStreamer(result) << LL_ENDL;
+ LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << result << LL_ENDL;
continue;
}
@@ -254,7 +263,7 @@ namespace Details
}
// was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
- LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << LLSDXMLStreamer(acknowledge) << ")" << LL_ENDL;
+ LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << acknowledge << ")" << LL_ENDL;
LLSD::array_const_iterator i = events.beginArray();
LLSD::array_const_iterator end = events.endArray();
diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h
index 09e0cd8821..5cc5bf685f 100644
--- a/indra/newview/llexperiencelog.h
+++ b/indra/newview/llexperiencelog.h
@@ -62,10 +62,9 @@ public:
static std::string getPermissionString(const LLSD& message, const std::string& base);
void setEventsToSave(LLSD new_events){mEventsToSave = new_events; }
bool isNotExpired(std::string& date);
-protected:
void handleExperienceMessage(LLSD& message);
-
+protected:
void loadEvents();
void saveEvents();
void eraseExpired();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 1587903a15..4a802ad9aa 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -153,7 +153,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
}
mTEOffset = -1;
- mTextureIndex = 255;
+ mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES;
setDrawable(drawablep);
mVObjp = objp;
@@ -168,7 +168,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
- mHasMedia = FALSE ;
+ mHasMedia = false ;
+ mIsMediaAllowed = true;
}
void LLFace::destroy()
@@ -183,6 +184,7 @@ void LLFace::destroy()
if(mTexture[i].notNull())
{
mTexture[i]->removeFace(i, this) ;
+ mTexture[i] = NULL;
}
}
@@ -194,7 +196,7 @@ void LLFace::destroy()
if (mDrawPoolp)
{
- if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
+ if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR))
{
((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this);
}
@@ -202,7 +204,6 @@ void LLFace::destroy()
{
mDrawPoolp->removeFace(this);
}
-
mDrawPoolp = NULL;
}
@@ -211,7 +212,7 @@ void LLFace::destroy()
delete mTextureMatrix;
mTextureMatrix = NULL;
- if (mDrawablep.notNull())
+ if (mDrawablep)
{
LLSpatialGroup* group = mDrawablep->getSpatialGroup();
if (group)
@@ -223,7 +224,7 @@ void LLFace::destroy()
}
setDrawInfo(NULL);
-
+
mDrawablep = NULL;
mVObjp = NULL;
}
@@ -302,6 +303,11 @@ void LLFace::setDiffuseMap(LLViewerTexture* tex)
setTexture(LLRender::DIFFUSE_MAP, tex);
}
+void LLFace::setAlternateDiffuseMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, tex);
+}
+
void LLFace::setNormalMap(LLViewerTexture* tex)
{
setTexture(LLRender::NORMAL_MAP, tex);
@@ -450,7 +456,7 @@ void LLFace::setTextureIndex(U8 index)
{
mTextureIndex = index;
- if (mTextureIndex != 255)
+ if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES)
{
mDrawablep->setState(LLDrawable::REBUILD_POSITION);
}
@@ -529,7 +535,7 @@ void LLFace::updateCenterAgent()
void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
{
- if (mDrawablep->getSpatialGroup() == NULL)
+ if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL)
{
return;
}
@@ -537,7 +543,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
mDrawablep->getSpatialGroup()->rebuildGeom();
mDrawablep->getSpatialGroup()->rebuildMesh();
- if(mDrawablep.isNull() || mVertexBuffer.isNull())
+ if(mVertexBuffer.isNull())
{
return;
}
@@ -1414,17 +1420,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (shiny_in_alpha)
{
-
- static const GLfloat alpha[4] =
+ static const GLfloat SHININESS_TO_ALPHA[4] =
{
- 0.00f,
+ 0.0000f,
0.25f,
0.5f,
0.75f
};
llassert(tep->getShiny() <= 3);
- color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
+ color.mV[3] = U8 (SHININESS_TO_ALPHA[tep->getShiny()] * 255);
}
}
}
@@ -1534,7 +1539,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
- U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+ U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
S32 val = 0;
U8* vp = (U8*) &val;
@@ -1710,7 +1715,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
// that emboss mapping always shows up on the upward faces of cubes when
// it's noon (since a lot of builders build with the sun forced to noon).
LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
- LLVector3 moon_ray = gSky.getMoonDirection();
+ LLVector3 moon_ray = gSky.mVOSkyp->getMoon().getDirection();
LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
@@ -2067,7 +2072,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a texIdx;
- S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
+ S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
F32 val = 0.f;
S32* vp = (S32*) &val;
@@ -2668,7 +2673,7 @@ S32 LLFace::renderElements(const U16 *index_array) const
S32 LLFace::renderIndexed()
{
- if(mDrawablep.isNull() || mDrawPoolp == NULL)
+ if(mDrawablep == NULL || mDrawPoolp == NULL)
{
return 0;
}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 77861f7d2f..3611539ff8 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -52,6 +52,7 @@ class LLDrawInfo;
const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
+const U8 FACE_DO_NOT_BATCH_TEXTURES = 255;
class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16>
{
@@ -104,6 +105,7 @@ public:
void setDiffuseMap(LLViewerTexture* tex);
void setNormalMap(LLViewerTexture* tex);
void setSpecularMap(LLViewerTexture* tex);
+ void setAlternateDiffuseMap(LLViewerTexture* tex);
void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
@@ -217,6 +219,9 @@ public:
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
+ void setMediaAllowed(bool is_media_allowed) { mIsMediaAllowed = is_media_allowed; }
+ BOOL isMediaAllowed() const { return mIsMediaAllowed; }
+
BOOL switchTexture() ;
//vertex buffer tracking
@@ -275,8 +280,13 @@ private:
LLXformMatrix* mXform;
LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
-
- LLPointer<LLDrawable> mDrawablep;
+
+ // mDrawablep is not supposed to be null, don't use LLPointer because
+ // mDrawablep owns LLFace and LLPointer is a good way to either cause a
+ // memory leak or a 'delete each other' situation if something deletes
+ // drawable wrongly.
+ LLDrawable* mDrawablep;
+ // LLViewerObject technically owns drawable, but also it should be strictly managed
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;
@@ -292,6 +302,7 @@ private:
F32 mImportanceToCamera ;
F32 mBoundingSphereRadius ;
bool mHasMedia ;
+ bool mIsMediaAllowed;
protected:
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index d90f03b403..239d162101 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -130,7 +130,7 @@ BOOL LLFastTimerView::postBuild()
{
LLButton& pause_btn = getChildRef<LLButton>("pause_btn");
mScrollBar = getChild<LLScrollbar>("scroll_vert");
-
+
pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this));
return TRUE;
}
@@ -361,12 +361,12 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
}
else
{
- setPauseState(true);
- mScrollIndex = llclamp(mScrollIndex + clicks,
- 0,
- llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
+ setPauseState(true);
+ mScrollIndex = llclamp( mScrollIndex + clicks,
+ 0,
+ llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
}
- return TRUE;
+ return TRUE;
}
static BlockTimerStatHandle FTM_RENDER_TIMER("Timers");
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 5b4b7789b4..83b5bf3f25 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
#include "lltooltip.h"
#include "llagent.h"
+#include "llagentpicksinfo.h"
#include "llavatarnamecache.h"
#include "llclipboard.h"
#include "llinventorybridge.h"
@@ -384,6 +385,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
mUpdateDropDownItems(true),
mRestoreOverflowMenu(false),
mGetPrevItems(true),
+ mMouseX(0),
+ mMouseY(0),
mItemsChangedTimer()
{
// Register callback for menus with current registrar (will be parent panel's registrar)
@@ -399,8 +402,10 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
//make chevron button
LLTextBox::Params more_button_params(p.more_button);
mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params);
- mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+ mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));
addChild(mMoreTextBox);
+ LLRect rect = mMoreTextBox->getRect();
+ mMoreTextBox->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom));
mDropDownItemsCount = 0;
@@ -975,6 +980,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
return TRUE;
}
+void LLFavoritesBarCtrl::onMoreTextBoxClicked()
+{
+ LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY);
+ showDropDownMenu();
+}
+
void LLFavoritesBarCtrl::showDropDownMenu()
{
if (mOverflowMenuHandle.isDead())
@@ -1130,7 +1141,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)
}
}
- LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+ LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY);
}
void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
@@ -1194,6 +1205,10 @@ bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata)
{
return isClipboardPasteable();
}
+ else if (param == "create_pick")
+ {
+ return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
+ }
return false;
}
@@ -1242,6 +1257,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
LLFloaterReg::showInstance("world_map", "center");
}
}
+ else if (action == "create_pick")
+ {
+ LLSD args;
+ args["type"] = "create_pick";
+ args["item_id"] = item->getUUID();
+ LLFloaterSidePanelContainer::showPanel("places", args);
+ }
else if (action == "cut")
{
}
@@ -1257,6 +1279,20 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
{
gInventory.removeItem(mSelectedItemID);
}
+ else if (action == "rename")
+ {
+ LLSD args;
+ args["NAME"] = item->getName();
+
+ LLSD payload;
+ payload["id"] = mSelectedItemID;
+
+ LLNotificationsUtil::add("RenameLandmark", args, payload, boost::bind(onRenameCommit, _1, _2));
+ }
+ else if (action == "move_to_landmarks")
+ {
+ change_item_parent(mSelectedItemID, gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
+ }
// Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).
// See EXT-4217 and STORM-207.
@@ -1269,6 +1305,28 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
}
+bool LLFavoritesBarCtrl::onRenameCommit(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ LLUUID id = notification["payload"]["id"].asUUID();
+ LLInventoryItem *item = gInventory.getItem(id);
+ std::string landmark_name = response["new_name"].asString();
+ LLStringUtil::trim(landmark_name);
+
+ if (!landmark_name.empty() && item && item->getName() != landmark_name)
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->rename(landmark_name);
+ new_item->updateServer(FALSE);
+ gInventory.updateItem(new_item);
+ }
+ }
+
+ return false;
+}
+
BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
{
if (!LLClipboard::instance().hasContents())
@@ -1493,19 +1551,25 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
}
// static
-std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
+std::string LLFavoritesOrderStorage::getStoredFavoritesFilename(const std::string &grid)
{
- std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
return (user_dir.empty() ? ""
: gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"stored_favorites_"
- + LLGridManager::getInstance()->getGrid()
+ + grid
+ ".xml")
);
}
// static
+std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
+{
+ return getStoredFavoritesFilename(LLGridManager::getInstance()->getGrid());
+}
+
+// static
void LLFavoritesOrderStorage::destroyClass()
{
LLFavoritesOrderStorage::instance().cleanup();
@@ -1584,14 +1648,29 @@ void LLFavoritesOrderStorage::load()
<< (fav_llsd.isMap() ? "" : "un") << "successfully"
<< LL_ENDL;
in_file.close();
- user_llsd = fav_llsd[gAgentUsername];
+ if (fav_llsd.isMap() && fav_llsd.has(gAgentUsername))
+ {
+ user_llsd = fav_llsd[gAgentUsername];
- S32 index = 0;
- for (LLSD::array_iterator iter = user_llsd.beginArray();
+ S32 index = 0;
+ bool needs_validation = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
+ for (LLSD::array_iterator iter = user_llsd.beginArray();
iter != user_llsd.endArray(); ++iter)
- {
- mSortIndexes.insert(std::make_pair(iter->get("id").asUUID(), index));
- index++;
+ {
+ // Validation
+ LLUUID fv_id = iter->get("id").asUUID();
+ if (needs_validation
+ && (fv_id.isNull()
+ || iter->get("asset_id").asUUID().isNull()
+ || iter->get("name").asString().empty()
+ || iter->get("slurl").asString().empty()))
+ {
+ mRecreateFavoriteStorage = true;
+ }
+
+ mSortIndexes.insert(std::make_pair(fv_id, index));
+ index++;
+ }
}
}
else
@@ -1602,6 +1681,64 @@ void LLFavoritesOrderStorage::load()
}
}
+// static
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser(const std::string &user, const std::string &grid)
+{
+ std::string filename = getStoredFavoritesFilename(grid);
+ if (!filename.empty())
+ {
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, file);
+ file.close();
+
+ // Note : use the "John Doe" and not the "john.doe" version of the name.
+ // See saveFavoritesSLURLs() here above for the reason why.
+ if (fav_llsd.has(user))
+ {
+ LLSD user_llsd = fav_llsd[user];
+
+ if ((user_llsd.beginArray() != user_llsd.endArray()) && user_llsd.beginArray()->has("id"))
+ {
+ for (LLSD::array_iterator iter = user_llsd.beginArray(); iter != user_llsd.endArray(); ++iter)
+ {
+ LLSD value;
+ value["id"] = iter->get("id").asUUID();
+ iter->assign(value);
+ }
+ fav_llsd[user] = user_llsd;
+ llofstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+ file.close();
+ }
+ }
+ else
+ {
+ LL_INFOS("FavoritesBar") << "Removed favorites for " << user << LL_ENDL;
+ fav_llsd.erase(user);
+ }
+ }
+
+ llofstream out_file;
+ out_file.open(filename.c_str());
+ if (out_file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+ LL_INFOS("FavoritesBar") << "saved favorites to '" << filename << "' "
+ << LL_ENDL;
+ out_file.close();
+ }
+ }
+ }
+}
+
+// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
{
std::string filename = getStoredFavoritesFilename();
@@ -1777,6 +1914,8 @@ void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_it
BOOL LLFavoritesOrderStorage::saveFavoritesRecord(bool pref_changed)
{
+ pref_changed |= mRecreateFavoriteStorage;
+ mRecreateFavoriteStorage = false;
LLUUID favorite_folder= gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
if (favorite_folder.isNull())
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index cac32c7f2a..3bb940948b 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -91,11 +91,14 @@ protected:
bool enableSelected(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
+ static bool onRenameCommit(const LLSD& notification, const LLSD& response);
BOOL isClipboardPasteable() const;
void pasteFromClipboard() const;
void showDropDownMenu();
+ void onMoreTextBoxClicked();
+
LLHandle<LLView> mOverflowMenuHandle;
LLHandle<LLView> mContextMenuHandle;
@@ -163,6 +166,9 @@ private:
BOOL mTabsHighlightEnabled;
+ S32 mMouseX;
+ S32 mMouseY;
+
boost::signals2::connection mEndDragConnection;
};
@@ -208,9 +214,15 @@ public:
* @see cleanup()
*/
static void destroyClass();
+ static std::string getStoredFavoritesFilename(const std::string &grid);
static std::string getStoredFavoritesFilename();
static std::string getSavedOrderFileName();
+ // Remove record of specified user's favorites from file on disk.
+ static void removeFavoritesRecordOfUser(const std::string &user, const std::string &grid);
+ // Remove record of current user's favorites from file on disk.
+ static void removeFavoritesRecordOfUser();
+
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
@@ -232,9 +244,6 @@ private:
void load();
- // Remove record of current user's favorites from file on disk.
- void removeFavoritesRecordOfUser();
-
void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
@@ -245,6 +254,7 @@ private:
slurls_map_t mSLURLs;
std::set<LLUUID> mMissingSLURLs;
bool mIsDirty;
+ bool mRecreateFavoriteStorage;
struct IsNotInFavorites
{
@@ -275,7 +285,9 @@ private:
inline
LLFavoritesOrderStorage::LLFavoritesOrderStorage() :
- mIsDirty(false), mUpdateRequired(false)
+ mIsDirty(false),
+ mUpdateRequired(false),
+ mRecreateFavoriteStorage(false)
{ load(); }
#endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index aa9cba0c18..e6bbe234b3 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -379,22 +379,6 @@ F32 gpu_benchmark();
#if LL_WINDOWS
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
- if (code == STATUS_MSC_EXCEPTION)
- {
- // C++ exception, go on
- return EXCEPTION_CONTINUE_SEARCH;
- }
- else
- {
- // handle it
- return EXCEPTION_EXECUTE_HANDLER;
- }
-}
-
F32 logExceptionBenchmark()
{
// Todo: make a wrapper/class for SEH exceptions
@@ -403,7 +387,7 @@ F32 logExceptionBenchmark()
{
gbps = gpu_benchmark();
}
- __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation()))
+ __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
{
// convert to C++ styled exception
char integer_string[32];
@@ -617,36 +601,36 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
- LLViewerShaderMgr::sSkipReload = true;
+ LLViewerShaderMgr::sSkipReload = true;
- applyBaseMasks();
+ applyBaseMasks();
- // if we're passed an invalid level, default to "Low"
- std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
- if (features == "Low")
- {
+ // if we're passed an invalid level, default to "Low"
+ std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+ if (features == "Low")
+ {
#if LL_DARWIN
- // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
- // systems which support them instead of falling back to fixed-function unnecessarily
- // MAINT-2157
- if (gGLManager.mGLVersion < 2.1f)
+ // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+ // systems which support them instead of falling back to fixed-function unnecessarily
+ // MAINT-2157
+ if (gGLManager.mGLVersion < 2.1f)
#else
- // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
- if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+ // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+ if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
#endif
- {
+ {
// same as Low, but with "Basic Shaders" disabled
- features = "LowFixedFunction";
- }
- }
+ features = "LowFixedFunction";
+ }
+ }
- maskFeatures(features);
+ maskFeatures(features);
- applyFeatures(skipFeatures);
+ applyFeatures(skipFeatures);
- LLViewerShaderMgr::sSkipReload = false;
- LLViewerShaderMgr::instance()->setShaders();
- gPipeline.refreshCachedSettings();
+ LLViewerShaderMgr::sSkipReload = false;
+ LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.refreshCachedSettings();
}
void LLFeatureManager::applyBaseMasks()
@@ -771,12 +755,7 @@ void LLFeatureManager::applyBaseMasks()
maskFeatures("RAM256MB");
}
-#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast
-#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
- if (gSysCPU.getMHz() < 800)
-#else
if (gSysCPU.getMHz() < 1100)
-#endif
{
maskFeatures("CPUSlow");
}
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index b6fd70452e..3669fb1eeb 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -40,7 +40,7 @@
#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers
#endif // LL_SDL
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
#include "llhttpconstants.h" // file picker uses some of thes constants on Linux
#endif
@@ -939,7 +939,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
}
//END LL_DARWIN
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
# if LL_GTK
@@ -1504,4 +1504,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
return FALSE;
}
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
diff --git a/indra/newview/llfloateraddpaymentmethod.cpp b/indra/newview/llfloateraddpaymentmethod.cpp
new file mode 100644
index 0000000000..3952b48229
--- /dev/null
+++ b/indra/newview/llfloateraddpaymentmethod.cpp
@@ -0,0 +1,81 @@
+/**
+ * @file llfloateraddpaymentmethod.cpp
+ * @brief LLFloaterAddPaymentMethod class implementation
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateraddpaymentmethod.h"
+#include "llnotificationsutil.h"
+#include "lluictrlfactory.h"
+#include "llweb.h"
+
+
+LLFloaterAddPaymentMethod::LLFloaterAddPaymentMethod(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterAddPaymentMethod::~LLFloaterAddPaymentMethod()
+{
+}
+
+BOOL LLFloaterAddPaymentMethod::postBuild()
+{
+ setCanDrag(FALSE);
+ getChild<LLButton>("continue_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onContinueBtn, this));
+ getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onCloseBtn, this));
+ return TRUE;
+}
+
+void LLFloaterAddPaymentMethod::onOpen(const LLSD& key)
+{
+ centerOnScreen();
+}
+
+void LLFloaterAddPaymentMethod::onContinueBtn()
+{
+ closeFloater();
+ LLNotificationsUtil::add("AddPaymentMethod", LLSD(), LLSD(),
+ [this](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ LLWeb::loadURL(this->getString("continue_url"));
+ }
+ });
+}
+
+void LLFloaterAddPaymentMethod::onCloseBtn()
+{
+ closeFloater();
+}
+
+void LLFloaterAddPaymentMethod::centerOnScreen()
+{
+ LLVector2 window_size = LLUI::getInstance()->getWindowSize();
+ centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
+}
+
diff --git a/indra/newview/llfloateraddpaymentmethod.h b/indra/newview/llfloateraddpaymentmethod.h
new file mode 100644
index 0000000000..b3bb624484
--- /dev/null
+++ b/indra/newview/llfloateraddpaymentmethod.h
@@ -0,0 +1,52 @@
+/**
+ * @file llfloateraddpaymentmethod.h
+ * @brief LLFloaterAddPaymentMethod class definition
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATER_ADDPAYMENTMETHOD_H
+#define LL_FLOATER_ADDPAYMENTMETHOD_H
+
+#include "llfloater.h"
+
+class LLFloaterAddPaymentMethod:
+ public LLFloater
+{
+ friend class LLFloaterReg;
+public:
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+ LLFloaterAddPaymentMethod(const LLSD& key);
+
+ void centerOnScreen();
+
+ void onCloseBtn();
+ void onContinueBtn();
+
+ /*virtual*/ ~LLFloaterAddPaymentMethod();
+
+};
+
+#endif
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 56619e818a..957b2e1e8e 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -182,8 +182,11 @@ void LLFloaterAuction::onClickSnapshot(void* data)
BOOL success = gViewerWindow->rawSnapshot(raw,
gViewerWindow->getWindowWidthScaled(),
gViewerWindow->getWindowHeightScaled(),
- TRUE, FALSE,
- FALSE, FALSE);
+ TRUE,
+ FALSE,
+ FALSE, //UI
+ FALSE, //HUD
+ FALSE);
gForceRenderLandFence = FALSE;
if (success)
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 33099db1b9..ab95bc06b8 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -361,59 +361,8 @@ void LLFloaterAvatarPicker::populateFriend()
void LLFloaterAvatarPicker::drawFrustum()
{
- if(mFrustumOrigin.get())
- {
- LLView * frustumOrigin = mFrustumOrigin.get();
- LLRect origin_rect;
- frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
- // draw context cone connecting color picker with color swatch in parent floater
- LLRect local_rect = getLocalRect();
- if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::QUADS);
- {
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- }
- gGL.end();
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- }
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
}
void LLFloaterAvatarPicker::draw()
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 8e654a53c4..ebb73fc1f7 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -55,7 +55,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
{
for (U32 i=0; i < TEX_NUM_INDICES; i++)
{
- const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+ const std::string tex_name = LLAvatarAppearance::getDictionary()->getTexture(ETextureIndex(i))->mName;
mTextures[i] = getChild<LLTextureCtrl>(tex_name);
}
mTitle = getTitle();
@@ -77,7 +77,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
ETextureIndex te)
{
LLUUID id = IMG_DEFAULT_AVATAR;
- const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture(te);
if (tex_entry && tex_entry->mIsLocalTexture)
{
if (avatarp->isSelf())
@@ -165,14 +165,14 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
const LLTextureEntry* te = avatarp->getTE(i);
if (!te) continue;
- const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)(i));
if (!tex_entry)
continue;
if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
{
LLUUID id = IMG_DEFAULT_AVATAR;
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)i);
if (avatarp->isSelf())
{
LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index f2040bc760..a1a06706bc 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -75,6 +75,7 @@ BOOL LLFloaterBulkPermission::postBuild()
mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts");
mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
+ mBulkChangeIncludeSettings = gSavedSettings.getBOOL("BulkChangeIncludeSettings");
mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
@@ -186,6 +187,7 @@ void LLFloaterBulkPermission::onCloseBtn()
gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts);
gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
+ gSavedSettings.setBOOL("BulkChangeIncludeSettings", mBulkChangeIncludeSettings);
gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
@@ -281,6 +283,7 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check)
gSavedSettings.setBOOL("BulkChangeIncludeScripts" , check);
gSavedSettings.setBOOL("BulkChangeIncludeSounds" , check);
gSavedSettings.setBOOL("BulkChangeIncludeTextures" , check);
+ gSavedSettings.setBOOL("BulkChangeIncludeSettings" , check);
}
@@ -302,6 +305,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
( asstype == LLAssetType::AT_OBJECT && gSavedSettings.getBOOL("BulkChangeIncludeObjects" )) ||
( 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_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" )))
{
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
@@ -333,7 +337,12 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
//|| something else // for next owner perms
)
{
- perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("BulkChange"));
+ U32 mask_next = LLFloaterPerms::getNextOwnerPerms("BulkChange");
+ if (asstype == LLAssetType::AT_SETTINGS)
+ {
+ mask_next |= PERM_COPY;
+ }
+ perm.setMaskNext(mask_next);
perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("BulkChange"));
perm.setMaskGroup(LLFloaterPerms::getGroupPerms("BulkChange"));
new_item->setPermissions(perm); // here's the beef
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 0c042c3ee3..1afc876bba 100644
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -102,6 +102,7 @@ private:
bool mBulkChangeIncludeScripts;
bool mBulkChangeIncludeSounds;
bool mBulkChangeIncludeTextures;
+ bool mBulkChangeIncludeSettings;
bool mBulkChangeShareWithGroup;
bool mBulkChangeEveryoneCopy;
bool mBulkChangeNextOwnerModify;
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index 5a9cdbba44..ea93d3bfaa 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -49,7 +49,8 @@
#include "lltrans.h"
LLFloaterBuy::LLFloaterBuy(const LLSD& key)
-: LLFloater(key)
+: LLFloater(key),
+ mSelectionUpdateSlot()
{
}
@@ -179,12 +180,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name);
+ floater->showViews(true);
+
// Must do this after the floater is created, because
// sometimes the inventory is already there and
// the callback is called immediately.
LLViewerObject* obj = selection->getFirstRootObject();
floater->registerVOInventoryListener(obj,NULL);
floater->requestVOInventory();
+
+ if (!floater->mSelectionUpdateSlot.connected())
+ {
+ floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater));
+ }
}
void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
@@ -241,7 +249,7 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
BOOL item_is_multi = FALSE;
if (( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK))
{
item_is_multi = TRUE;
}
@@ -280,6 +288,30 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
removeVOInventoryListener();
}
+void LLFloaterBuy::onSelectionChanged()
+{
+
+ if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0)
+ {
+ removeVOInventoryListener();
+ closeFloater();
+ }
+ else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1)
+ {
+ removeVOInventoryListener();
+ showViews(false);
+ reset();
+ setTitle(getString("mupliple_selected"));
+ }
+}
+
+void LLFloaterBuy::showViews(bool show)
+{
+ getChild<LLUICtrl>("buy_btn")->setEnabled(show);
+ getChild<LLUICtrl>("buy_text")->setVisible(show);
+ getChild<LLUICtrl>("buy_name_text")->setVisible(show);
+}
+
void LLFloaterBuy::onClickBuy()
{
// Put the items where we put new folders.
@@ -303,5 +335,10 @@ void LLFloaterBuy::onClickCancel()
// virtual
void LLFloaterBuy::onClose(bool app_quitting)
{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
+
mObjectSelection.clear();
}
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 3ec642dee1..e83b3c6ba6 100644
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
@@ -63,12 +63,17 @@ protected:
S32 serial_num,
void* data);
+ void onSelectionChanged();
+ void showViews(bool show);
+
void onClickBuy();
void onClickCancel();
private:
LLSafeHandle<LLObjectSelection> mObjectSelection;
LLSaleInfo mSaleInfo;
+
+ boost::signals2::connection mSelectionUpdateSlot;
};
#endif
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index 4607b4ac41..440ec06c4e 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -216,7 +216,7 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
BOOL item_is_multi = FALSE;
if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK))
{
item_is_multi = TRUE;
}
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 91436e52fe..0cfac166c7 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -32,6 +32,8 @@
#include "llcurrencyuimanager.h"
#include "llfloater.h"
#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "lliconctrl.h"
#include "llnotificationsutil.h"
#include "llstatusbar.h"
#include "lltextbox.h"
@@ -42,7 +44,6 @@
#include "llwindow.h"
#include "llappviewer.h"
-static const S32 STANDARD_BUY_AMOUNT = 2000;
static const S32 MINIMUM_BALANCE_AMOUNT = 0;
class LLFloaterBuyCurrencyUI
@@ -58,8 +59,8 @@ public:
LLCurrencyUIManager mManager;
bool mHasTarget;
- std::string mTargetName;
S32 mTargetPrice;
+ S32 mRequiredAmount;
public:
void noTarget();
@@ -68,13 +69,13 @@ public:
virtual BOOL postBuild();
void updateUI();
+ void collapsePanels(bool collapse);
virtual void draw();
virtual BOOL canClose();
void onClickBuy();
void onClickCancel();
- void onClickErrorWeb();
};
LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
@@ -93,7 +94,9 @@ LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)
: LLFloater(key),
mChildren(*this),
- mManager(*this)
+ mManager(*this),
+ mHasTarget(false),
+ mTargetPrice(0)
{
}
@@ -105,15 +108,20 @@ LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()
void LLFloaterBuyCurrencyUI::noTarget()
{
mHasTarget = false;
- mManager.setAmount(STANDARD_BUY_AMOUNT);
+ mTargetPrice = 0;
+ mManager.setAmount(0);
}
void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
{
mHasTarget = true;
- mTargetName = name;
mTargetPrice = price;
+ if (!name.empty())
+ {
+ getChild<LLUICtrl>("target_price_label")->setValue(name);
+ }
+
S32 balance = gStatusBar->getBalance();
S32 need = price - balance;
if (need < 0)
@@ -121,7 +129,8 @@ void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
need = 0;
}
- mManager.setAmount(need + MINIMUM_BALANCE_AMOUNT);
+ mRequiredAmount = need + MINIMUM_BALANCE_AMOUNT;
+ mManager.setAmount(0);
}
@@ -132,7 +141,6 @@ BOOL LLFloaterBuyCurrencyUI::postBuild()
getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this));
getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this));
- getChild<LLUICtrl>("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickErrorWeb, this));
center();
@@ -173,42 +181,25 @@ void LLFloaterBuyCurrencyUI::updateUI()
// hide most widgets - we'll turn them on as needed next
getChildView("info_buying")->setVisible(FALSE);
- getChildView("info_cannot_buy")->setVisible(FALSE);
getChildView("info_need_more")->setVisible(FALSE);
getChildView("purchase_warning_repurchase")->setVisible(FALSE);
getChildView("purchase_warning_notenough")->setVisible(FALSE);
getChildView("contacting")->setVisible(FALSE);
- getChildView("buy_action")->setVisible(FALSE);
if (hasError)
{
// display an error from the server
- getChildView("normal_background")->setVisible(FALSE);
- getChildView("error_background")->setVisible(TRUE);
- getChildView("info_cannot_buy")->setVisible(TRUE);
- getChildView("cannot_buy_message")->setVisible(TRUE);
- getChildView("balance_label")->setVisible(FALSE);
- getChildView("balance_amount")->setVisible(FALSE);
- getChildView("buying_label")->setVisible(FALSE);
- getChildView("buying_amount")->setVisible(FALSE);
- getChildView("total_label")->setVisible(FALSE);
- getChildView("total_amount")->setVisible(FALSE);
-
- LLTextBox* message = getChild<LLTextBox>("cannot_buy_message");
- if (message)
- {
- message->setText(mManager.errorMessage());
- }
-
- getChildView("error_web")->setVisible( !mManager.errorURI().empty());
+ LLSD args;
+ args["TITLE"] = getString("info_cannot_buy");
+ args["MESSAGE"] = mManager.errorMessage();
+ LLNotificationsUtil::add("CouldNotBuyCurrency", args);
+ mManager.clearError();
+ closeFloater();
}
else
{
// display the main Buy L$ interface
getChildView("normal_background")->setVisible(TRUE);
- getChildView("error_background")->setVisible(FALSE);
- getChildView("cannot_buy_message")->setVisible(FALSE);
- getChildView("error_web")->setVisible(FALSE);
if (mHasTarget)
{
@@ -227,8 +218,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
{
if (mHasTarget)
{
- getChildView("buy_action")->setVisible( true);
- getChild<LLUICtrl>("buy_action")->setTextArg("[ACTION]", mTargetName);
+ getChild<LLUICtrl>("target_price")->setTextArg("[AMT]", llformat("%d", mTargetPrice));
+ getChild<LLUICtrl>("required_amount")->setTextArg("[AMT]", llformat("%d", mRequiredAmount));
}
}
@@ -249,18 +240,40 @@ void LLFloaterBuyCurrencyUI::updateUI()
if (mHasTarget)
{
- if (total >= mTargetPrice)
- {
- getChildView("purchase_warning_repurchase")->setVisible( true);
- }
- else
- {
- getChildView("purchase_warning_notenough")->setVisible( true);
- }
+ getChildView("purchase_warning_repurchase")->setVisible( !getChildView("currency_links")->getVisible());
}
}
- getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError);
+ getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible());
+}
+
+void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse)
+{
+ LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price");
+
+ if (price_panel->isCollapsed() == collapse)
+ return;
+
+ LLLayoutStack* outer_stack = getChild<LLLayoutStack>("outer_stack");
+ LLLayoutPanel* required_panel = getChild<LLLayoutPanel>("layout_panel_required");
+ LLLayoutPanel* msg_panel = getChild<LLLayoutPanel>("layout_panel_msg");
+
+ S32 delta_height = price_panel->getRect().getHeight() + required_panel->getRect().getHeight() + msg_panel->getRect().getHeight();
+ delta_height *= (collapse ? -1 : 1);
+
+ LLIconCtrl* icon = getChild<LLIconCtrl>("normal_background");
+ LLRect rect = icon->getRect();
+ icon->setRect(rect.setOriginAndSize(rect.mLeft, rect.mBottom - delta_height, rect.getWidth(), rect.getHeight() + delta_height));
+
+ outer_stack->collapsePanel(price_panel, collapse);
+ outer_stack->collapsePanel(required_panel, collapse);
+ outer_stack->collapsePanel(msg_panel, collapse);
+
+ outer_stack->updateLayout();
+
+ LLRect floater_rect = getRect();
+ floater_rect.mBottom -= delta_height;
+ setShape(floater_rect, false);
}
void LLFloaterBuyCurrencyUI::onClickBuy()
@@ -278,28 +291,72 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
LLStatusBar::sendMoneyBalanceRequest();
}
-void LLFloaterBuyCurrencyUI::onClickErrorWeb()
-{
- LLWeb::loadURL(mManager.errorURI());
- closeFloater();
- // Update L$ balance
- LLStatusBar::sendMoneyBalanceRequest();
-}
+LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL;
// static
void LLFloaterBuyCurrency::buyCurrency()
{
- LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
- ui->noTarget();
- ui->updateUI();
+ delete sPropertiesRequest;
+ sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
}
// static
void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)
{
- LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
- ui->target(name, price);
- ui->updateUI();
+ delete sPropertiesRequest;
+ sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
}
+// static
+void LLFloaterBuyCurrency::handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price)
+{
+ delete sPropertiesRequest;
+ sPropertiesRequest = NULL;
+
+ if (has_piof)
+ {
+ LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
+ if (has_target)
+ {
+ ui->target(name, price);
+ }
+ else
+ {
+ ui->noTarget();
+ }
+ ui->updateUI();
+ ui->collapsePanels(!has_target);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("add_payment_method");
+ }
+}
+
+LLFetchAvatarPaymentInfo::LLFetchAvatarPaymentInfo(bool has_target, const std::string& name, S32 price)
+: mAvatarID(gAgent.getID()),
+ mHasTarget(has_target),
+ mPrice(price),
+ mName(name)
+{
+ LLAvatarPropertiesProcessor* processor = LLAvatarPropertiesProcessor::getInstance();
+ // register ourselves as an observer
+ processor->addObserver(mAvatarID, this);
+ // send a request (duplicates will be suppressed inside the avatar
+ // properties processor)
+ processor->sendAvatarPropertiesRequest(mAvatarID);
+}
+
+LLFetchAvatarPaymentInfo::~LLFetchAvatarPaymentInfo()
+{
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this);
+}
+void LLFetchAvatarPaymentInfo::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (data && type == APT_PROPERTIES)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ LLFloaterBuyCurrency::handleBuyCurrency(LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(avatar_data), mHasTarget, mName, mPrice);
+ }
+}
diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h
index 7ff6c42384..88d3d17cd6 100644
--- a/indra/newview/llfloaterbuycurrency.h
+++ b/indra/newview/llfloaterbuycurrency.h
@@ -27,15 +27,34 @@
#ifndef LL_LLFLOATERBUYCURRENCY_H
#define LL_LLFLOATERBUYCURRENCY_H
+#include "llavatarpropertiesprocessor.h"
#include "stdtypes.h"
-
+#include "llagent.h"
class LLFloater;
+class LLFetchAvatarPaymentInfo : public LLAvatarPropertiesObserver
+{
+public:
+ LLFetchAvatarPaymentInfo(bool has_target, const std::string& name = std::string(), S32 price = 0);
+ ~LLFetchAvatarPaymentInfo();
+
+ void processProperties(void* data, EAvatarProcessorType type);
+
+private:
+ LLUUID mAvatarID;
+ bool mHasTarget;
+ std::string mName;
+ S32 mPrice;
+};
+
+
class LLFloaterBuyCurrency
{
public:
static void buyCurrency();
static void buyCurrency(const std::string& name, S32 price);
+
+ static void handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price);
/* name should be a noun phrase of the object or service being bought:
"That object costs"
"Trying to give"
@@ -44,7 +63,8 @@ public:
*/
static LLFloater* buildFloater(const LLSD& key);
-};
+ static LLFetchAvatarPaymentInfo* sPropertiesRequest;
+};
#endif
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index ee7e6f8562..131d9b077b 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -31,13 +31,13 @@
#include "llbvhloader.h"
#include "lldatapacker.h"
#include "lldir.h"
-#include "lleconomy.h"
#include "llnotificationsutil.h"
#include "llvfile.h"
#include "llapr.h"
#include "llstring.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llanimationstates.h"
#include "llbbox.h"
#include "llbutton.h"
@@ -68,7 +68,8 @@
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
-const S32 PREF_BUTTON_HEIGHT = 16;
+const S32 PREVIEW_VPAD = 35;
+const S32 PREF_BUTTON_HEIGHT = 16 + 35;
const S32 PREVIEW_TEXTURE_HEIGHT = 300;
const F32 PREVIEW_CAMERA_DISTANCE = 4.f;
@@ -203,7 +204,7 @@ BOOL LLFloaterBvhPreview::postBuild()
setDefaultBtn();
mPreviewRect.set(PREVIEW_HPAD,
- PREVIEW_TEXTURE_HEIGHT,
+ PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
getRect().getWidth() - PREVIEW_HPAD,
PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
@@ -403,13 +404,13 @@ void LLFloaterBvhPreview::draw()
gGL.begin( LLRender::QUADS );
{
gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
gGL.texCoord2f(0.f, 0.f);
gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(1.f, 0.f);
gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
}
gGL.end();
@@ -1004,16 +1005,18 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
{
std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();
std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString();
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ S32 expected_upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
- LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo(
+ LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
floaterp->mTransactionID, LLAssetType::AT_ANIMATION,
name, desc, 0,
LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION,
- LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost));
- upload_new_resource(assetUpdloadInfo);
+ upload_new_resource(assetUploadInfo);
}
else
{
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index f3406d93bb..3b192ff81b 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -34,6 +34,7 @@
// Viewer includes
#include "llagent.h"
#include "llagentcamera.h"
+#include "llpresetsmanager.h"
#include "lljoystickbutton.h"
#include "llviewercontrol.h"
#include "llviewercamera.h"
@@ -42,6 +43,8 @@
#include "llslider.h"
#include "llfirstuse.h"
#include "llhints.h"
+#include "lltabcontainer.h"
+#include "llvoavatarself.h"
static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item");
@@ -52,7 +55,6 @@ const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
#define ORBIT "cam_rotate_stick"
#define PAN "cam_track_stick"
#define ZOOM "zoom"
-#define PRESETS "preset_views_list"
#define CONTROLS "controls"
bool LLFloaterCamera::sFreeCamera = false;
@@ -269,13 +271,7 @@ void LLFloaterCamera::onAvatarEditingAppearance(bool editing)
void LLFloaterCamera::handleAvatarEditingAppearance(bool editing)
{
- //camera presets (rear, front, etc.)
- getChildView("preset_views_list")->setEnabled(!editing);
- getChildView("presets_btn")->setEnabled(!editing);
- //camera modes (object view, mouselook view)
- getChildView("camera_modes_list")->setEnabled(!editing);
- getChildView("avatarview_btn")->setEnabled(!editing);
}
void LLFloaterCamera::update()
@@ -322,6 +318,8 @@ void LLFloaterCamera::onOpen(const LLSD& key)
else
toPrevMode();
mClosed = FALSE;
+
+ populatePresetCombo();
}
void LLFloaterCamera::onClose(bool app_quitting)
@@ -353,6 +351,8 @@ LLFloaterCamera::LLFloaterCamera(const LLSD& val)
{
LLHints::getInstance()->registerHintTarget("view_popup", getHandle());
mCommitCallbackRegistrar.add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2));
+ mCommitCallbackRegistrar.add("CameraPresets.Save", boost::bind(&LLFloaterCamera::onSavePreset, this));
+ mCommitCallbackRegistrar.add("CameraPresets.ShowPresetsList", boost::bind(&LLFloaterReg::showInstance, "camera_presets", LLSD(), FALSE));
}
// virtual
@@ -363,10 +363,14 @@ BOOL LLFloaterCamera::postBuild()
mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
mZoom = findChild<LLPanelCameraZoom>(ZOOM);
mTrack = getChild<LLJoystickCameraTrack>(PAN);
+ mPresetCombo = getChild<LLComboBox>("preset_combo");
+
+ getChild<LLTextBox>("precise_ctrs_label")->setShowCursorHand(false);
+ getChild<LLTextBox>("precise_ctrs_label")->setSoundFlags(LLView::MOUSE_UP);
+ getChild<LLTextBox>("precise_ctrs_label")->setClickedCallback(boost::bind(&LLFloaterReg::showInstance, "prefs_view_advanced", LLSD(), FALSE));
- assignButton2Mode(CAMERA_CTRL_MODE_MODES, "avatarview_btn");
- assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn");
- assignButton2Mode(CAMERA_CTRL_MODE_PRESETS, "presets_btn");
+ mPresetCombo->setCommitCallback(boost::bind(&LLFloaterCamera::onCustomPresetSelected, this));
+ LLPresetsManager::getInstance()->setPresetListChangeCameraCallback(boost::bind(&LLFloaterCamera::populatePresetCombo, this));
update();
@@ -376,6 +380,15 @@ BOOL LLFloaterCamera::postBuild()
return LLFloater::postBuild();
}
+F32 LLFloaterCamera::getCurrentTransparency()
+{
+
+ static LLCachedControl<F32> camera_opacity(gSavedSettings, "CameraOpacity");
+ static LLCachedControl<F32> active_floater_transparency(gSavedSettings, "ActiveFloaterTransparency");
+ return llmin(camera_opacity(), active_floater_transparency());
+
+}
+
void LLFloaterCamera::fillFlatlistFromPanel (LLFlatListView* list, LLPanel* panel)
{
// copying child list and then iterating over a copy, because list itself
@@ -444,13 +457,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
switch (mode)
{
- case CAMERA_CTRL_MODE_MODES:
- if(sFreeCamera)
- {
- switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
- }
- break;
-
+ case CAMERA_CTRL_MODE_PRESETS:
case CAMERA_CTRL_MODE_PAN:
sFreeCamera = false;
clear_camera_tool();
@@ -461,49 +468,14 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
activate_camera_tool();
break;
- case CAMERA_CTRL_MODE_PRESETS:
- if(sFreeCamera)
- {
- switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
- }
- break;
-
default:
//normally we won't occur here
llassert_always(FALSE);
}
}
-
-void LLFloaterCamera::onClickBtn(ECameraControlMode mode)
-{
- // check for a click on active button
- if (mCurrMode == mode) mMode2Button[mode]->setToggleState(TRUE);
-
- switchMode(mode);
-
-}
-
-void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name)
-{
- LLButton* button = getChild<LLButton>(button_name);
-
- button->setClickedCallback(boost::bind(&LLFloaterCamera::onClickBtn, this, mode));
- mMode2Button[mode] = button;
-}
-
void LLFloaterCamera::updateState()
{
- getChildView(ZOOM)->setVisible(CAMERA_CTRL_MODE_PAN == mCurrMode);
-
- bool show_presets = (CAMERA_CTRL_MODE_PRESETS == mCurrMode) || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
- && CAMERA_CTRL_MODE_PRESETS == mPrevMode);
- getChildView(PRESETS)->setVisible(show_presets);
-
- bool show_camera_modes = CAMERA_CTRL_MODE_MODES == mCurrMode || (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode
- && CAMERA_CTRL_MODE_MODES == mPrevMode);
- getChildView("camera_modes_list")->setVisible( show_camera_modes);
-
updateItemsSelection();
if (CAMERA_CTRL_MODE_FREE_CAMERA == mCurrMode)
@@ -521,13 +493,13 @@ void LLFloaterCamera::updateState()
void LLFloaterCamera::updateItemsSelection()
{
- ECameraPreset preset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
+ ECameraPreset preset = (ECameraPreset) gSavedSettings.getU32("CameraPresetType");
LLSD argument;
- argument["selected"] = preset == CAMERA_PRESET_REAR_VIEW;
+ argument["selected"] = (preset == CAMERA_PRESET_REAR_VIEW) && !sFreeCamera;
getChild<LLPanelCameraItem>("rear_view")->setValue(argument);
- argument["selected"] = preset == CAMERA_PRESET_GROUP_VIEW;
+ argument["selected"] = (preset == CAMERA_PRESET_GROUP_VIEW) && !sFreeCamera;
getChild<LLPanelCameraItem>("group_view")->setValue(argument);
- argument["selected"] = preset == CAMERA_PRESET_FRONT_VIEW;
+ argument["selected"] = (preset == CAMERA_PRESET_FRONT_VIEW) && !sFreeCamera;
getChild<LLPanelCameraItem>("front_view")->setValue(argument);
argument["selected"] = gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK;
getChild<LLPanelCameraItem>("mouselook_view")->setValue(argument);
@@ -547,19 +519,18 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param)
{
LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
if (camera_floater)
- camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
+ {
+ camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
+ camera_floater->updateItemsSelection();
+ }
}
else
{
+ LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
+ if (camera_floater)
+ camera_floater->switchMode(CAMERA_CTRL_MODE_PAN);
switchToPreset(name);
}
-
- LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
- if (camera_floater)
- {
- camera_floater->updateItemsSelection();
- camera_floater->fromFreeToPresets();
- }
}
/*static*/
@@ -567,24 +538,85 @@ void LLFloaterCamera::switchToPreset(const std::string& name)
{
sFreeCamera = false;
clear_camera_tool();
- if ("rear_view" == name)
+ if (PRESETS_REAR_VIEW == name)
{
gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
}
- else if ("group_view" == name)
+ else if (PRESETS_SIDE_VIEW == name)
{
gAgentCamera.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
}
- else if ("front_view" == name)
+ else if (PRESETS_FRONT_VIEW == name)
{
gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
}
+ else
+ {
+ gAgentCamera.switchCameraPreset(CAMERA_PRESET_CUSTOM);
+ }
+
+ if (gSavedSettings.getString("PresetCameraActive") != name)
+ {
+ LLPresetsManager::getInstance()->loadPreset(PRESETS_CAMERA, name);
+ }
+
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ LLQuaternion sit_rot(gSavedSettings.getLLSD("AvatarSitRotation"));
+ if (sit_rot != LLQuaternion())
+ {
+ gAgent.rotate(~gAgent.getFrameAgent().getQuaternion());
+ gAgent.rotate(sit_rot);
+ }
+ else
+ {
+ gAgentCamera.rotateToInitSitRot();
+ }
+ }
+ gAgentCamera.resetCameraZoomFraction();
+
+ LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
+ if (camera_floater)
+ {
+ camera_floater->updateItemsSelection();
+ camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS);
+ }
+}
+
+void LLFloaterCamera::populatePresetCombo()
+{
+ LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, EDefaultOptions::DEFAULT_HIDE);
+ std::string active_preset_name = gSavedSettings.getString("PresetCameraActive");
+ if (active_preset_name.empty())
+ {
+ gSavedSettings.setU32("CameraPresetType", CAMERA_PRESET_CUSTOM);
+ updateItemsSelection();
+ mPresetCombo->setLabel(getString("inactive_combo_text"));
+ }
+ else if ((ECameraPreset)gSavedSettings.getU32("CameraPresetType") == CAMERA_PRESET_CUSTOM)
+ {
+ mPresetCombo->selectByValue(active_preset_name);
+ }
+ else
+ {
+ mPresetCombo->setLabel(getString("inactive_combo_text"));
+ }
+ updateItemsSelection();
+}
+
+void LLFloaterCamera::onSavePreset()
+{
+ LLFloaterReg::hideInstance("delete_pref_preset", PRESETS_CAMERA);
+ LLFloaterReg::hideInstance("load_pref_preset", PRESETS_CAMERA);
+
+ LLFloaterReg::showInstance("save_camera_preset");
}
-void LLFloaterCamera::fromFreeToPresets()
+void LLFloaterCamera::onCustomPresetSelected()
{
- if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS)
+ std::string selected_preset = mPresetCombo->getSelectedItemLabel();
+ if (getString("inactive_combo_text") != selected_preset)
{
- switchMode(CAMERA_CTRL_MODE_PRESETS);
+ switchToPreset(selected_preset);
}
}
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 4d6d03f22d..a69b87ad16 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -36,10 +36,10 @@ class LLJoystickCameraRotate;
class LLJoystickCameraTrack;
class LLFloaterReg;
class LLPanelCameraZoom;
+class LLComboBox;
enum ECameraControlMode
{
- CAMERA_CTRL_MODE_MODES,
CAMERA_CTRL_MODE_PAN,
CAMERA_CTRL_MODE_FREE_CAMERA,
CAMERA_CTRL_MODE_PRESETS
@@ -50,7 +50,6 @@ class LLFloaterCamera : public LLFloater
friend class LLFloaterReg;
public:
-
/* whether in free camera mode */
static bool inFreeCameraMode();
/* callback for camera items selection changing */
@@ -70,13 +69,14 @@ public:
/*switch to one of the camera presets (front, rear, side)*/
static void switchToPreset(const std::string& name);
- /* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and
- are not in free camera mode*/
- void fromFreeToPresets();
-
virtual void onOpen(const LLSD& key);
virtual void onClose(bool app_quitting);
+ void onSavePreset();
+ void onCustomPresetSelected();
+
+ void populatePresetCombo();
+
LLJoystickCameraRotate* mRotate;
LLPanelCameraZoom* mZoom;
LLJoystickCameraTrack* mTrack;
@@ -91,6 +91,10 @@ private:
/*virtual*/ BOOL postBuild();
+ F32 getCurrentTransparency();
+
+ void onViewButtonClick(const LLSD& user_data);
+
ECameraControlMode determineMode();
/* resets to the previous mode */
@@ -108,9 +112,6 @@ private:
/* update camera modes items selection and camera preset items selection according to the currently selected preset */
void updateItemsSelection();
- void onClickBtn(ECameraControlMode mode);
- void assignButton2Mode(ECameraControlMode mode, const std::string& button_name);
-
// fills flatlist with items from given panel
void fillFlatlistFromPanel (LLFlatListView* list, LLPanel* panel);
@@ -124,6 +125,8 @@ private:
ECameraControlMode mPrevMode;
ECameraControlMode mCurrMode;
std::map<ECameraControlMode, LLButton*> mMode2Button;
+
+ LLComboBox* mPresetCombo;
};
/**
diff --git a/indra/newview/llfloatercamerapresets.cpp b/indra/newview/llfloatercamerapresets.cpp
new file mode 100644
index 0000000000..300c945a85
--- /dev/null
+++ b/indra/newview/llfloatercamerapresets.cpp
@@ -0,0 +1,145 @@
+/**
+* @file llfloatercamerapresets.cpp
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* 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$
+*/
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatercamerapresets.h"
+#include "llfloaterreg.h"
+#include "llnotificationsutil.h"
+#include "llpresetsmanager.h"
+#include "llviewercontrol.h"
+
+LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key)
+: LLFloater(key)
+{}
+
+LLFloaterCameraPresets::~LLFloaterCameraPresets()
+{}
+
+BOOL LLFloaterCameraPresets::postBuild()
+{
+ mPresetList = getChild<LLFlatListView>("preset_list");
+
+ LLPresetsManager::getInstance()->setPresetListChangeCameraCallback(boost::bind(&LLFloaterCameraPresets::populateList, this));
+
+ return TRUE;
+}
+void LLFloaterCameraPresets::onOpen(const LLSD& key)
+{
+ populateList();
+}
+
+void LLFloaterCameraPresets::populateList()
+{
+ mPresetList->clear();
+
+ LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
+ std::list<std::string> preset_names;
+
+ presetsMgr->loadPresetNamesFromDir(PRESETS_CAMERA, preset_names, DEFAULT_BOTTOM);
+
+ for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
+ {
+ const std::string& name = *it;
+ bool is_default = presetsMgr->isDefaultCameraPreset(name);
+ LLCameraPresetFlatItem* item = new LLCameraPresetFlatItem(name, is_default);
+ item->postBuild();
+ mPresetList->addItem(item);
+ }
+}
+
+LLCameraPresetFlatItem::LLCameraPresetFlatItem(const std::string &preset_name, bool is_default)
+ : LLPanel(),
+ mPresetName(preset_name),
+ mIsDefaultPrest(is_default)
+{
+ mCommitCallbackRegistrar.add("CameraPresets.Delete", boost::bind(&LLCameraPresetFlatItem::onDeleteBtnClick, this));
+ mCommitCallbackRegistrar.add("CameraPresets.Reset", boost::bind(&LLCameraPresetFlatItem::onResetBtnClick, this));
+ buildFromFile("panel_camera_preset_item.xml");
+}
+
+LLCameraPresetFlatItem::~LLCameraPresetFlatItem()
+{
+}
+
+BOOL LLCameraPresetFlatItem::postBuild()
+{
+ mDeleteBtn = getChild<LLButton>("delete_btn");
+ mDeleteBtn->setVisible(false);
+
+ mResetBtn = getChild<LLButton>("reset_btn");
+ mResetBtn->setVisible(false);
+
+ LLStyle::Params style;
+ LLTextBox* name_text = getChild<LLTextBox>("preset_name");
+ LLFontDescriptor new_desc(name_text->getFont()->getFontDesc());
+ new_desc.setStyle(mIsDefaultPrest ? LLFontGL::ITALIC : LLFontGL::NORMAL);
+ LLFontGL* new_font = LLFontGL::getFont(new_desc);
+ style.font = new_font;
+ name_text->setText(mPresetName, style);
+
+ return true;
+}
+
+void LLCameraPresetFlatItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mDeleteBtn->setVisible(!mIsDefaultPrest);
+ mResetBtn->setVisible(mIsDefaultPrest);
+ getChildView("hovered_icon")->setVisible(true);
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLCameraPresetFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mDeleteBtn->setVisible(false);
+ mResetBtn->setVisible(false);
+ getChildView("hovered_icon")->setVisible(false);
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLCameraPresetFlatItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLCameraPresetFlatItem::onDeleteBtnClick()
+{
+ if (!LLPresetsManager::getInstance()->deletePreset(PRESETS_CAMERA, mPresetName))
+ {
+ LLSD args;
+ args["NAME"] = mPresetName;
+ LLNotificationsUtil::add("PresetNotDeleted", args);
+ }
+ else if (gSavedSettings.getString("PresetCameraActive") == mPresetName)
+ {
+ gSavedSettings.setString("PresetCameraActive", "");
+ }
+}
+
+void LLCameraPresetFlatItem::onResetBtnClick()
+{
+ LLPresetsManager::getInstance()->resetCameraPreset(mPresetName);
+}
diff --git a/indra/newview/llfloatercamerapresets.h b/indra/newview/llfloatercamerapresets.h
new file mode 100644
index 0000000000..66430fa399
--- /dev/null
+++ b/indra/newview/llfloatercamerapresets.h
@@ -0,0 +1,73 @@
+/**
+* @file llfloatercamerapresets.h
+*
+* $LicenseInfo:firstyear=2019&license=viewerlgpl$
+* Second Life Viewer Source Code
+* 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$
+*/
+#ifndef LLFLOATERCAMERAPRESETS_H
+#define LLFLOATERCAMERAPRESETS_H
+
+#include "llfloater.h"
+#include "llflatlistview.h"
+
+class LLFloaterReg;
+
+class LLFloaterCameraPresets : public LLFloater
+{
+ friend class LLFloaterReg;
+
+ virtual BOOL postBuild();
+ virtual void onOpen(const LLSD& key);
+
+ void populateList();
+
+private:
+ LLFloaterCameraPresets(const LLSD& key);
+ ~LLFloaterCameraPresets();
+
+ LLFlatListView* mPresetList;
+};
+
+class LLCameraPresetFlatItem : public LLPanel
+{
+public:
+ LLCameraPresetFlatItem(const std::string &preset_name, bool is_default);
+ virtual ~LLCameraPresetFlatItem();
+
+ void setValue(const LLSD& value);
+
+ virtual BOOL postBuild();
+ virtual void onMouseEnter(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+private:
+ void onDeleteBtnClick();
+ void onResetBtnClick();
+
+ LLButton* mDeleteBtn;
+ LLButton* mResetBtn;
+
+ std::string mPresetName;
+ bool mIsDefaultPrest;
+
+};
+
+#endif
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index ec2c9740af..1a784223c2 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -485,56 +485,8 @@ BOOL LLFloaterColorPicker::isColorChanged()
//
void LLFloaterColorPicker::draw()
{
- LLRect swatch_rect;
- mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
- // draw context cone connecting color picker with color swatch in parent floater
- LLRect local_rect = getLocalRect();
- if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::QUADS);
- {
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
- }
- gGL.end();
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),
- LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
- }
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mSwatch, mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
mApplyImmediateCheck->setEnabled(mActive && mCanApplyImmediately);
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 55561fa128..580a3f2610 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -50,6 +50,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
mShowHistory(false),
mMessages(NULL),
mHistoryThreadsBusy(false),
+ mIsGroup(false),
mOpened(false)
{
}
@@ -75,6 +76,7 @@ BOOL LLFloaterConversationPreview::postBuild()
{
name = conv->getConversationName();
file = conv->getHistoryFileName();
+ mIsGroup = (LLIMModel::LLIMSession::GROUP_SESSION == conv->getConversationType());
}
else
{
@@ -82,6 +84,10 @@ BOOL LLFloaterConversationPreview::postBuild()
file = "chat";
}
mChatHistoryFileName = file;
+ if (mIsGroup && !LLStringUtil::endsWith(mChatHistoryFileName, GROUP_CHAT_SUFFIX))
+ {
+ mChatHistoryFileName += GROUP_CHAT_SUFFIX;
+ }
LLStringUtil::format_map_t args;
args["[NAME]"] = name;
std::string title = getString("Title", args);
@@ -145,6 +151,7 @@ void LLFloaterConversationPreview::onOpen(const LLSD& key)
LLSD load_params;
load_params["load_all_history"] = true;
load_params["cut_off_todays_date"] = false;
+ load_params["is_group"] = mIsGroup;
// The temporary message list with "Loading..." text
// Will be deleted upon loading completion in setPages() method
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index a8dbbc9ffe..7ca4ee6945 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -66,6 +66,7 @@ private:
bool mShowHistory;
bool mHistoryThreadsBusy;
bool mOpened;
+ bool mIsGroup;
};
#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
new file mode 100644
index 0000000000..eb93a6a75a
--- /dev/null
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -0,0 +1,323 @@
+/**
+ * @file llfloatercreatelandmark.cpp
+ * @brief LLFloaterCreateLandmark class implementation
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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 "llfloatercreatelandmark.h"
+
+#include "llagent.h"
+#include "llagentui.h"
+#include "llcombobox.h"
+#include "llinventoryfunctions.h"
+#include "llinventoryobserver.h"
+#include "lllandmarkactions.h"
+#include "llnotificationsutil.h"
+#include "llpanellandmarkinfo.h"
+#include "llparcel.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lluictrlfactory.h"
+#include "llviewermessage.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+typedef std::pair<LLUUID, std::string> folder_pair_t;
+
+class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+{
+public:
+ LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
+ mFloater(create_landmark_floater)
+ {}
+
+protected:
+ /*virtual*/ void done()
+ {
+ mFloater->setItem(gInventory.getAddedIDs());
+ }
+
+private:
+ LLFloaterCreateLandmark* mFloater;
+};
+
+LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key)
+ : LLFloater("add_landmark"),
+ mItem(NULL)
+{
+ mInventoryObserver = new LLLandmarksInventoryObserver(this);
+}
+
+LLFloaterCreateLandmark::~LLFloaterCreateLandmark()
+{
+ removeObserver();
+}
+
+BOOL LLFloaterCreateLandmark::postBuild()
+{
+ mFolderCombo = getChild<LLComboBox>("folder_combo");
+ mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
+ mNotesEditor = getChild<LLTextEditor>("notes_editor");
+
+ getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this));
+ getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
+ getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+
+ mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
+
+ return TRUE;
+}
+
+void LLFloaterCreateLandmark::removeObserver()
+{
+ if (gInventory.containsObserver(mInventoryObserver))
+ gInventory.removeObserver(mInventoryObserver);
+}
+
+void LLFloaterCreateLandmark::onOpen(const LLSD& key)
+{
+ LLUUID dest_folder = LLUUID();
+ if (key.has("dest_folder"))
+ {
+ dest_folder = key["dest_folder"].asUUID();
+ }
+ mItem = NULL;
+ gInventory.addObserver(mInventoryObserver);
+ setLandmarkInfo(dest_folder);
+ populateFoldersList(dest_folder);
+}
+
+void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id)
+{
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+ LLParcel* parcel = parcel_mgr->getAgentParcel();
+ std::string name = parcel->getName();
+ LLVector3 agent_pos = gAgent.getPositionAgent();
+
+ if (name.empty())
+ {
+ S32 region_x = ll_round(agent_pos.mV[VX]);
+ S32 region_y = ll_round(agent_pos.mV[VY]);
+ S32 region_z = ll_round(agent_pos.mV[VZ]);
+
+ std::string region_name;
+ LLViewerRegion* region = parcel_mgr->getSelectionRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+ else
+ {
+ std::string desc;
+ LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
+ region_name = desc;
+ }
+
+ mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)",
+ region_name.c_str(), region_x, region_y, region_z));
+ }
+ else
+ {
+ mLandmarkTitleEditor->setText(name);
+ }
+
+ LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
+}
+
+bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
+{
+ return left.second < right.second;
+}
+
+void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
+{
+ // Collect all folders that can contain landmarks.
+ LLInventoryModel::cat_array_t cats;
+ LLPanelLandmarkInfo::collectLandmarkFolders(cats);
+
+ mFolderCombo->removeall();
+
+ // Put the "My Favorites" folder first in list.
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
+ if (!favorites_cat)
+ {
+ LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
+ }
+ else
+ {
+ mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID());
+ }
+
+ // Add the "Landmarks" category.
+ const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID);
+ if (!lmcat)
+ {
+ LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL;
+ }
+ else
+ {
+ std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat);
+ mFolderCombo->add(cat_full_name, lmcat->getUUID());
+ }
+
+ typedef std::vector<folder_pair_t> folder_vec_t;
+ folder_vec_t folders;
+ // Sort the folders by their full name.
+ for (S32 i = 0; i < cats.size(); i++)
+ {
+ const LLViewerInventoryCategory* cat = cats.at(i);
+ std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat);
+ folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
+ }
+ sort(folders.begin(), folders.end(), cmp_folders);
+
+ // Finally, populate the combobox.
+ for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
+ mFolderCombo->add(it->second, LLSD(it->first));
+
+ if (folder_id.notNull())
+ {
+ mFolderCombo->setCurrentByID(folder_id);
+ }
+}
+
+void LLFloaterCreateLandmark::onCreateFolderClicked()
+{
+ LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
+ [this](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ std::string folder_name = resp["message"].asString();
+ if (!folder_name.empty())
+ {
+ inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1);
+ gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func);
+ gInventory.notifyObservers();
+ }
+ }
+ });
+}
+
+void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
+{
+ populateFoldersList(folder_id);
+}
+
+void LLFloaterCreateLandmark::onSaveClicked()
+{
+ if (mItem.isNull())
+ {
+ closeFloater();
+ 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);
+
+ LLUUID item_id = mItem->getUUID();
+ LLUUID folder_id = mFolderCombo->getValue().asUUID();
+ bool change_parent = folder_id != mItem->getParentUUID();
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ LLPointer<LLInventoryCallback> cb;
+ if (change_parent)
+ {
+ cb = new LLUpdateLandmarkParent(new_item, folder_id);
+ }
+ LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+ gInventory.accountForUpdate(up);
+ update_inventory_item(new_item, cb);
+ }
+ else if (change_parent)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ new_item->setParent(folder_id);
+ new_item->updateParentOnServer(FALSE);
+ }
+
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+
+ closeFloater();
+}
+
+void LLFloaterCreateLandmark::onCancelClicked()
+{
+ if (!mItem.isNull())
+ {
+ LLUUID item_id = mItem->getUUID();
+ remove_inventory_item(item_id, NULL);
+ }
+ closeFloater();
+}
+
+
+void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
+{
+ for (uuid_set_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLUUID& item_id = (*item_iter);
+ if(!highlight_offered_object(item_id))
+ {
+ continue;
+ }
+
+ LLInventoryItem* item = gInventory.getItem(item_id);
+
+ llassert(item);
+ if (item && (LLAssetType::AT_LANDMARK == item->getType()) )
+ {
+ if(!getItem())
+ {
+ removeObserver();
+ mItem = item;
+ break;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
new file mode 100644
index 0000000000..74ac5e651c
--- /dev/null
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -0,0 +1,74 @@
+/**
+ * @file llfloatercreatelandmark.h
+ * @brief LLFloaterCreateLandmark class definition
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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_LLFLOATERCREATELANDMARK_H
+#define LL_LLFLOATERCREATELANDMARK_H
+
+#include "llfloater.h"
+
+class LLComboBox;
+class LLInventoryItem;
+class LLLineEditor;
+class LLTextEditor;
+class LLLandmarksInventoryObserver;
+
+class LLFloaterCreateLandmark:
+ public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+
+ LLFloaterCreateLandmark(const LLSD& key);
+ ~LLFloaterCreateLandmark();
+
+ BOOL postBuild();
+ void onOpen(const LLSD& key);
+
+ void setItem(const uuid_set_t& items);
+
+ LLInventoryItem* getItem() { return mItem; }
+
+private:
+ void setLandmarkInfo(const LLUUID &folder_id);
+ void removeObserver();
+ void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+ void onCreateFolderClicked();
+ void onSaveClicked();
+ void onCancelClicked();
+
+ void folderCreatedCallback(LLUUID folder_id);
+
+ LLComboBox* mFolderCombo;
+ LLLineEditor* mLandmarkTitleEditor;
+ LLTextEditor* mNotesEditor;
+ LLUUID mLandmarksID;
+
+ LLLandmarksInventoryObserver* mInventoryObserver;
+ LLPointer<LLInventoryItem> mItem;
+};
+
+#endif
diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp
deleted file mode 100644
index bb11c813b4..0000000000
--- a/indra/newview/llfloaterdeleteenvpreset.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/**
- * @file llfloaterdeleteenvpreset.cpp
- * @brief Floater to delete a water / sky / day cycle preset.
- *
- * $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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterdeleteenvpreset.h"
-
-// libs
-#include "llbutton.h"
-#include "llcombobox.h"
-#include "llnotificationsutil.h"
-
-// newview
-#include "lldaycyclemanager.h"
-#include "llwaterparammanager.h"
-
-static bool confirmation_callback(const LLSD& notification, const LLSD& response, boost::function<void()> cb)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option == 0)
- {
- cb();
- }
- return false;
-
-}
-
-LLFloaterDeleteEnvPreset::LLFloaterDeleteEnvPreset(const LLSD &key)
-: LLFloater(key)
-, mPresetCombo(NULL)
-{
-}
-
-// virtual
-BOOL LLFloaterDeleteEnvPreset::postBuild()
-{
- mPresetCombo = getChild<LLComboBox>("preset_combo");
- mPresetCombo->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::postPopulate, this));
-
- getChild<LLButton>("delete")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnDelete, this));
- getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterDeleteEnvPreset::onBtnCancel, this));
-
- // Listen to user preferences change, in which case we need to rebuild the presets list
- // to disable the [new] current preset.
- LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populatePresetsList, this));
-
- // Listen to presets addition/removal.
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateDayCyclesList, this));
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateSkyPresetsList, this));
- LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterDeleteEnvPreset::populateWaterPresetsList, this));
-
- return TRUE;
-}
-
-// virtual
-void LLFloaterDeleteEnvPreset::onOpen(const LLSD& key)
-{
- std::string param = key.asString();
- std::string floater_title = getString(std::string("title_") + param);
- std::string combo_label = getString(std::string("label_" + param));
-
- // Update floater title.
- setTitle(floater_title);
-
- // Update the combobox label.
- getChild<LLUICtrl>("label")->setValue(combo_label);
-
- // Populate the combobox.
- populatePresetsList();
-}
-
-void LLFloaterDeleteEnvPreset::onBtnDelete()
-{
- std::string param = mKey.asString();
- std::string preset_name = mPresetCombo->getValue().asString();
- boost::function<void()> confirm_cb;
-
- if (param == "water")
- {
- // Don't allow deleting system presets.
- if (LLWaterParamManager::instance().isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation, this);
- }
- else if (param == "sky")
- {
- // Don't allow deleting presets referenced by local day cycles.
- if (LLDayCycleManager::instance().isSkyPresetReferenced(preset_name))
- {
- LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", getString("msg_sky_is_referenced")));
- return;
- }
-
- LLWLParamManager& wl_mgr = LLWLParamManager::instance();
-
- // Don't allow deleting system presets.
- if (wl_mgr.isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation, this);
- }
- else if (param == "day_cycle")
- {
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
-
- // Don't allow deleting system presets.
- if (day_mgr.isSystemPreset(preset_name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- confirm_cb = boost::bind(&LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation, this);
- }
- else
- {
- LL_WARNS() << "Unrecognized key" << LL_ENDL;
- }
-
- LLSD args;
- args["MESSAGE"] = getString("msg_confirm_deletion");
- LLNotificationsUtil::add("GenericAlertYesCancel", args, LLSD(),
- boost::bind(&confirmation_callback, _1, _2, confirm_cb));
-}
-
-void LLFloaterDeleteEnvPreset::onBtnCancel()
-{
- closeFloater();
-}
-
-void LLFloaterDeleteEnvPreset::populatePresetsList()
-{
- std::string param = mKey.asString();
-
- if (param == "water")
- {
- populateWaterPresetsList();
- }
- else if (param == "sky")
- {
- populateSkyPresetsList();
- }
- else if (param == "day_cycle")
- {
- populateDayCyclesList();
- }
- else
- {
- LL_WARNS() << "Unrecognized key" << LL_ENDL;
- }
-}
-
-void LLFloaterDeleteEnvPreset::populateWaterPresetsList()
-{
- if (mKey.asString() != "water") return;
-
- mPresetCombo->removeall();
-
- std::string cur_preset;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings())
- {
- cur_preset = env_mgr.getWaterPresetName();
- }
-
- LLWaterParamManager::preset_name_list_t presets;
- LLWaterParamManager::instance().getUserPresetNames(presets); // list only user presets
- for (LLWaterParamManager::preset_name_list_t::const_iterator it = presets.begin(); it != presets.end(); ++it)
- {
- std::string name = *it;
-
- bool enabled = (name != cur_preset); // don't allow deleting current preset
- mPresetCombo->add(name, ADD_BOTTOM, enabled);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::populateSkyPresetsList()
-{
- if (mKey.asString() != "sky") return;
-
- mPresetCombo->removeall();
-
- std::string cur_preset;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings() && env_mgr.getUseFixedSky())
- {
- cur_preset = env_mgr.getSkyPresetName();
- }
-
- LLWLParamManager::preset_name_list_t user_presets;
- LLWLParamManager::instance().getUserPresetNames(user_presets);
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- const std::string& name = *it;
- mPresetCombo->add(name, ADD_BOTTOM, /*enabled = */ name != cur_preset);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::populateDayCyclesList()
-{
- if (mKey.asString() != "day_cycle") return;
-
- mPresetCombo->removeall();
-
- std::string cur_day;
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (!env_mgr.getUseRegionSettings() && env_mgr.getUseDayCycle())
- {
- cur_day = env_mgr.getDayCycleName();
- }
-
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
- LLDayCycleManager::preset_name_list_t user_days;
- day_mgr.getUserPresetNames(user_days); // list only user presets
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- const std::string& name = *it;
- mPresetCombo->add(name, ADD_BOTTOM, name != cur_day);
- }
-
- postPopulate();
-}
-
-void LLFloaterDeleteEnvPreset::postPopulate()
-{
- // Handle empty list and empty selection.
- bool has_selection = mPresetCombo->getItemCount() > 0 && mPresetCombo->getSelectedValue().isDefined();
-
- if (!has_selection)
- {
- mPresetCombo->setLabel(getString("combo_label"));
- }
-
- getChild<LLButton>("delete")->setEnabled(has_selection);
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteDayCycleConfirmation()
-{
- LLDayCycleManager::instance().deletePreset(mPresetCombo->getValue().asString());
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteSkyPresetConfirmation()
-{
- LLWLParamKey key(mPresetCombo->getValue().asString(), LLEnvKey::SCOPE_LOCAL);
- LLWLParamManager::instance().removeParamSet(key, true);
-}
-
-void LLFloaterDeleteEnvPreset::onDeleteWaterPresetConfirmation()
-{
- LLWaterParamManager::instance().removeParamSet(mPresetCombo->getValue().asString(), true);
-}
diff --git a/indra/newview/llfloaterdeleteprefpreset.cpp b/indra/newview/llfloaterdeleteprefpreset.cpp
index 7dedbbf984..819b2bcee2 100644
--- a/indra/newview/llfloaterdeleteprefpreset.cpp
+++ b/indra/newview/llfloaterdeleteprefpreset.cpp
@@ -59,14 +59,25 @@ BOOL LLFloaterDeletePrefPreset::postBuild()
void LLFloaterDeletePrefPreset::onOpen(const LLSD& key)
{
mSubdirectory = key.asString();
- std::string floater_title = getString(std::string("title_") + mSubdirectory);
-
- setTitle(floater_title);
+ std::string title_type = std::string("title_") + mSubdirectory;
+ if (hasString(title_type))
+ {
+ std::string floater_title = getString(title_type);
+ setTitle(floater_title);
+ }
+ else
+ {
+ LL_WARNS() << title_type << " not found" << LL_ENDL;
+ setTitle(title_type);
+ }
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
-
EDefaultOptions option = DEFAULT_HIDE;
- LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+ bool action;
+ action = LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+
+ LLButton* delete_btn = getChild<LLButton>("delete");
+ delete_btn->setEnabled(action);
}
void LLFloaterDeletePrefPreset::onBtnDelete()
@@ -80,6 +91,13 @@ void LLFloaterDeletePrefPreset::onBtnDelete()
args["NAME"] = name;
LLNotificationsUtil::add("PresetNotDeleted", args);
}
+ else if (mSubdirectory == PRESETS_CAMERA)
+ {
+ if (gSavedSettings.getString("PresetCameraActive") == name)
+ {
+ gSavedSettings.setString("PresetCameraActive", "");
+ }
+ }
closeFloater();
}
@@ -87,12 +105,10 @@ void LLFloaterDeletePrefPreset::onBtnDelete()
void LLFloaterDeletePrefPreset::onPresetsListChange()
{
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
- LLButton* delete_btn = getChild<LLButton>("delete");
EDefaultOptions option = DEFAULT_HIDE;
- LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
- delete_btn->setEnabled(0 != combo->getItemCount());
+ LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
}
void LLFloaterDeletePrefPreset::onBtnCancel()
diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp
deleted file mode 100644
index 5c0991b0b3..0000000000
--- a/indra/newview/llfloatereditdaycycle.cpp
+++ /dev/null
@@ -1,825 +0,0 @@
-/**
- * @file llfloatereditdaycycle.cpp
- * @brief Floater to create or edit a day cycle
- *
- * $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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatereditdaycycle.h"
-
-// libs
-#include "llbutton.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llloadingindicator.h"
-#include "llmultisliderctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llspinctrl.h"
-#include "lltimectrl.h"
-
-// newview
-#include "llagent.h"
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
-#include "llregioninfomodel.h"
-#include "llviewerregion.h"
-#include "llwlparammanager.h"
-
-const F32 LLFloaterEditDayCycle::sHoursPerDay = 24.0f;
-
-LLFloaterEditDayCycle::LLFloaterEditDayCycle(const LLSD &key)
-: LLFloater(key)
-, mDayCycleNameEditor(NULL)
-, mDayCyclesCombo(NULL)
-, mTimeSlider(NULL)
-, mKeysSlider(NULL)
-, mSkyPresetsCombo(NULL)
-, mTimeCtrl(NULL)
-, mMakeDefaultCheckBox(NULL)
-, mSaveButton(NULL)
-{
-}
-
-// virtual
-BOOL LLFloaterEditDayCycle::postBuild()
-{
- mDayCycleNameEditor = getChild<LLLineEditor>("day_cycle_name");
- mDayCyclesCombo = getChild<LLComboBox>("day_cycle_combo");
-
- mTimeSlider = getChild<LLMultiSliderCtrl>("WLTimeSlider");
- mKeysSlider = getChild<LLMultiSliderCtrl>("WLDayCycleKeys");
- mSkyPresetsCombo = getChild<LLComboBox>("WLSkyPresets");
- mTimeCtrl = getChild<LLTimeCtrl>("time");
- mSaveButton = getChild<LLButton>("save");
- mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
-
- initCallbacks();
-
- // add the time slider
- mTimeSlider->addSlider();
-
- return TRUE;
-}
-
-// virtual
-void LLFloaterEditDayCycle::onOpen(const LLSD& key)
-{
- bool new_day = isNewDay();
- std::string param = key.asString();
- std::string floater_title = getString(std::string("title_") + param);
- std::string hint = getString(std::string("hint_" + param));
-
- // Update floater title.
- setTitle(floater_title);
-
- // Update the hint at the top.
- getChild<LLUICtrl>("hint")->setValue(hint);
-
- // Hide the hint to the right of the combo if we're invoked to create a new preset.
- getChildView("note")->setVisible(!new_day);
-
- // Switch between the day cycle presets combobox and day cycle name input field.
- mDayCyclesCombo->setVisible(!new_day);
- mDayCycleNameEditor->setVisible(new_day);
-
- // TODO: Make sure only one instance of the floater exists?
-
- reset();
-}
-
-// virtual
-void LLFloaterEditDayCycle::onClose(bool app_quitting)
-{
- if (!app_quitting) // there's no point to change environment if we're quitting
- {
- LLEnvManagerNew::instance().usePrefs(); // revert changes made to current day cycle
- }
-}
-
-// virtual
-void LLFloaterEditDayCycle::draw()
-{
- syncTimeSlider();
- LLFloater::draw();
-}
-
-void LLFloaterEditDayCycle::initCallbacks(void)
-{
- mDayCycleNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this), NULL);
- mDayCyclesCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleSelected, this));
- mDayCyclesCombo->setTextEntryCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleNameEdited, this));
- mTimeSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onTimeSliderMoved, this));
- mKeysSlider->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeMoved, this));
- mTimeCtrl->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyTimeChanged, this));
- mSkyPresetsCombo->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onKeyPresetChanged, this));
-
- getChild<LLButton>("WLAddKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onAddKey, this));
- getChild<LLButton>("WLDeleteKey")->setClickedCallback(boost::bind(&LLFloaterEditDayCycle::onDeleteKey, this));
-
- mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnSave, this));
- mSaveButton->setRightMouseDownCallback(boost::bind(&LLFloaterEditDayCycle::dumpTrack, this));
- getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditDayCycle::onBtnCancel, this));
-
- // Connect to env manager events.
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this));
- gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));
- env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1));
-
- // Connect to day cycle manager events.
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEditDayCycle::onDayCycleListChange, this));
-
- // Connect to sky preset list changes.
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditDayCycle::onSkyPresetListChange, this));
-
- // Connect to region info updates.
- LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditDayCycle::onRegionInfoUpdate, this));
-}
-
-void LLFloaterEditDayCycle::syncTimeSlider()
-{
- // set time
- mTimeSlider->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay);
-}
-
-void LLFloaterEditDayCycle::loadTrack()
-{
- // clear the slider
- mKeysSlider->clear();
- mSliderToKey.clear();
-
- // add sliders
-
- LL_DEBUGS() << "Adding " << LLWLParamManager::getInstance()->mDay.mTimeMap.size() << " keys to slider" << LL_ENDL;
-
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
- for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
- {
- addSliderKey(it->first * sHoursPerDay, it->second);
- }
-
- // set drop-down menu to match preset of currently-selected keyframe (one is automatically selected initially)
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- if (strlen(cur_sldr.c_str()) > 0) // only do this if there is a curSldr, otherwise we put an invalid entry into the map
- {
- mSkyPresetsCombo->selectByValue(mSliderToKey[cur_sldr].keyframe.toStringVal());
- }
-
- syncTimeSlider();
-}
-
-void LLFloaterEditDayCycle::applyTrack()
-{
- LL_DEBUGS() << "Applying track (" << mSliderToKey.size() << ")" << LL_ENDL;
-
- // if no keys, do nothing
- if (mSliderToKey.size() == 0)
- {
- LL_DEBUGS() << "No keys, not syncing" << LL_ENDL;
- return;
- }
-
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-
- // create a new animation track
- LLWLParamManager::getInstance()->mDay.clearKeyframes();
-
- // add the keys one by one
- for (std::map<std::string, SliderKey>::iterator it = mSliderToKey.begin();
- it != mSliderToKey.end(); ++it)
- {
- LLWLParamManager::getInstance()->mDay.addKeyframe(it->second.time / sHoursPerDay,
- it->second.keyframe);
- }
-
- // set the param manager's track to the new one
- LLWLParamManager::getInstance()->resetAnimator(
- mTimeSlider->getCurSliderValue() / sHoursPerDay, false);
-
- LLWLParamManager::getInstance()->mAnimator.update(
- LLWLParamManager::getInstance()->mCurParams);
-}
-
-void LLFloaterEditDayCycle::refreshSkyPresetsList()
-{
- // Don't allow selecting region skies for a local day cycle,
- // because thus we may end up with invalid day cycle.
- bool include_region_skies = getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION;
-
- mSkyPresetsCombo->removeall();
-
- LLWLParamManager::preset_name_list_t region_presets;
- LLWLParamManager::preset_name_list_t user_presets, sys_presets;
- LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
-
- if (include_region_skies)
- {
- // Add region presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
- {
- std::string preset_name = *it;
- std::string item_title = preset_name + " (" + getRegionName() + ")";
- mSkyPresetsCombo->add(preset_name, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toStringVal());
- }
-
- if (!region_presets.empty())
- {
- mSkyPresetsCombo->addSeparator();
- }
- }
-
- // Add user presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- if (!user_presets.empty())
- {
- mSkyPresetsCombo->addSeparator();
- }
-
- // Add system presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
- {
- mSkyPresetsCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- // set defaults on combo boxes
- mSkyPresetsCombo->selectFirstItem();
-}
-
-void LLFloaterEditDayCycle::refreshDayCyclesList()
-{
- llassert(isNewDay() == false);
-
- mDayCyclesCombo->removeall();
-
-#if 0 // Disable editing existing day cycle until the workflow is clear enough.
- const LLSD& region_day = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
- if (region_day.size() > 0)
- {
- LLWLParamKey key(getRegionName(), LLEnvKey::SCOPE_REGION);
- mDayCyclesCombo->add(key.name, key.toLLSD());
- mDayCyclesCombo->addSeparator();
- }
-#endif
-
- LLDayCycleManager::preset_name_list_t user_days, sys_days;
- LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
-
- // Add user days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- if (user_days.size() > 0)
- {
- mDayCyclesCombo->addSeparator();
- }
-
- // Add system days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
- {
- mDayCyclesCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- mDayCyclesCombo->setLabel(getString("combo_label"));
-}
-
-void LLFloaterEditDayCycle::onTimeSliderMoved()
-{
- /// get the slider value
- F32 val = mTimeSlider->getCurSliderValue() / sHoursPerDay;
-
- // set the value, turn off animation
- LLWLParamManager::getInstance()->mAnimator.setDayTime((F64)val);
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
- // then call update once
- LLWLParamManager::getInstance()->mAnimator.update(
- LLWLParamManager::getInstance()->mCurParams);
-}
-
-void LLFloaterEditDayCycle::onKeyTimeMoved()
-{
- if (mKeysSlider->getValue().size() == 0)
- {
- return;
- }
-
- // make sure we have a slider
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- if (cur_sldr == "")
- {
- return;
- }
-
- F32 time24 = mKeysSlider->getCurSliderValue();
-
- // check to see if a key exists
- LLWLParamKey key = mSliderToKey[cur_sldr].keyframe;
- LL_DEBUGS() << "Setting key time: " << time24 << LL_ENDL;
- mSliderToKey[cur_sldr].time = time24;
-
- // if it exists, turn on check box
- mSkyPresetsCombo->selectByValue(key.toStringVal());
-
- mTimeCtrl->setTime24(time24);
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onKeyTimeChanged()
-{
- // if no keys, skipped
- if (mSliderToKey.size() == 0)
- {
- return;
- }
-
- F32 time24 = mTimeCtrl->getTime24();
-
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
- mKeysSlider->setCurSliderValue(time24, TRUE);
- F32 time = mKeysSlider->getCurSliderValue() / sHoursPerDay;
-
- // now set the key's time in the sliderToKey map
- LL_DEBUGS() << "Setting key time: " << time << LL_ENDL;
- mSliderToKey[cur_sldr].time = time;
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onKeyPresetChanged()
-{
- // do nothing if no sliders
- if (mKeysSlider->getValue().size() == 0)
- {
- return;
- }
-
- // change the map
-
- std::string stringVal = mSkyPresetsCombo->getSelectedValue().asString();
- LLWLParamKey new_key(stringVal);
- llassert(!new_key.name.empty());
- const std::string& cur_sldr = mKeysSlider->getCurSlider();
-
- // if null, don't use
- if (cur_sldr == "")
- {
- return;
- }
-
- mSliderToKey[cur_sldr].keyframe = new_key;
-
- // Apply changes to current day cycle.
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onAddKey()
-{
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-
- S32 max_sliders;
- LLEnvKey::EScope scope = LLEnvKey::SCOPE_LOCAL; // *TODO: editing region day cycle
- switch (scope)
- {
- case LLEnvKey::SCOPE_LOCAL:
- max_sliders = 20; // *HACK this should be LLWLPacketScrubber::MAX_LOCAL_KEY_FRAMES;
- break;
- case LLEnvKey::SCOPE_REGION:
- max_sliders = 12; // *HACK this should be LLWLPacketScrubber::MAX_REGION_KEY_FRAMES;
- break;
- default:
- max_sliders = (S32) mKeysSlider->getMaxValue();
- break;
- }
-
- if ((S32)mSliderToKey.size() >= max_sliders)
- {
- LLSD args;
- args["SCOPE"] = LLEnvManagerNew::getScopeString(scope);
- args["MAX"] = max_sliders;
- LLNotificationsUtil::add("DayCycleTooManyKeyframes", args, LLSD(), LLNotificationFunctorRegistry::instance().DONOTHING);
- return;
- }
-
- // add the slider key
- std::string key_val = mSkyPresetsCombo->getSelectedValue().asString();
- LLWLParamKey sky_params(key_val);
- llassert(!sky_params.name.empty());
-
- F32 time = mTimeSlider->getCurSliderValue();
- addSliderKey(time, sky_params);
-
- // apply the change to current day cycles
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::addSliderKey(F32 time, LLWLParamKey keyframe)
-{
- // make a slider
- const std::string& sldr_name = mKeysSlider->addSlider(time);
- if (sldr_name.empty())
- {
- return;
- }
-
- // set the key
- SliderKey newKey(keyframe, mKeysSlider->getCurSliderValue());
-
- llassert_always(sldr_name != LLStringUtil::null);
-
- // add to map
- mSliderToKey.insert(std::pair<std::string, SliderKey>(sldr_name, newKey));
-
- llassert_always(mSliderToKey.size() == mKeysSlider->getValue().size());
-}
-
-LLWLParamKey LLFloaterEditDayCycle::getSelectedDayCycle()
-{
- LLWLParamKey dc_key;
-
- if (mDayCycleNameEditor->getVisible())
- {
- dc_key.name = mDayCycleNameEditor->getText();
- dc_key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- LLSD combo_val = mDayCyclesCombo->getValue();
-
- if (!combo_val.isArray()) // manually typed text
- {
- dc_key.name = combo_val.asString();
- dc_key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- dc_key.fromLLSD(combo_val);
- }
- }
-
- return dc_key;
-}
-
-bool LLFloaterEditDayCycle::isNewDay() const
-{
- return mKey.asString() == "new";
-}
-
-void LLFloaterEditDayCycle::dumpTrack()
-{
- LL_DEBUGS("Windlight") << "Dumping day cycle" << LL_ENDL;
-
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay;
- for (std::map<F32, LLWLParamKey>::iterator it = cur_dayp.mTimeMap.begin(); it != cur_dayp.mTimeMap.end(); ++it)
- {
- F32 time = it->first * 24.0f;
- S32 h = (S32) time;
- S32 m = (S32) ((time - h) * 60.0f);
- LL_DEBUGS("Windlight") << llformat("(%.3f) %02d:%02d", time, h, m) << " => " << it->second.name << LL_ENDL;
- }
-}
-
-void LLFloaterEditDayCycle::enableEditing(bool enable)
-{
- mSkyPresetsCombo->setEnabled(enable);
- mTimeCtrl->setEnabled(enable);
- getChild<LLPanel>("day_cycle_slider_panel")->setCtrlsEnabled(enable);
- mSaveButton->setEnabled(enable);
- mMakeDefaultCheckBox->setEnabled(enable);
-}
-
-void LLFloaterEditDayCycle::reset()
-{
- // clear the slider
- mKeysSlider->clear();
- mSliderToKey.clear();
-
- refreshSkyPresetsList();
-
- if (isNewDay())
- {
- mDayCycleNameEditor->setValue(LLSD());
- F32 time = 0.5f * sHoursPerDay;
- mSaveButton->setEnabled(FALSE); // will be enabled as soon as users enters a name
- mTimeSlider->setCurSliderValue(time);
-
- addSliderKey(time, LLWLParamKey("Default", LLEnvKey::SCOPE_LOCAL));
- onKeyTimeMoved(); // update the time control and sky sky combo
-
- applyTrack();
- }
- else
- {
- refreshDayCyclesList();
-
- // Disable controls until a day cycle to edit is selected.
- enableEditing(false);
- }
-}
-
-void LLFloaterEditDayCycle::saveRegionDayCycle()
-{
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- LLWLDayCycle& cur_dayp = LLWLParamManager::instance().mDay; // the day cycle being edited
-
- // Get current day cycle and the sky preset it references.
- LLSD day_cycle = cur_dayp.asLLSD();
- LLSD sky_map;
- cur_dayp.getSkyMap(sky_map);
-
- // Apply it to the region.
- LLEnvironmentSettings new_region_settings;
- new_region_settings.saveParams(day_cycle, sky_map, env_mgr.getRegionSettings().getWaterParams(), 0.0f);
-
-#if 1
- LLEnvManagerNew::instance().setRegionSettings(new_region_settings);
-#else // Temporary disabled ability to upload new region settings from the Day Cycle Editor.
- if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings))
- {
- LL_WARNS() << "Error applying region environment settings" << LL_ENDL;
- return;
- }
-
- setApplyProgress(true);
-#endif
-}
-
-void LLFloaterEditDayCycle::setApplyProgress(bool started)
-{
- LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator");
-
- indicator->setVisible(started);
-
- if (started)
- {
- indicator->start();
- }
- else
- {
- indicator->stop();
- }
-}
-
-bool LLFloaterEditDayCycle::getApplyProgress() const
-{
- return getChild<LLLoadingIndicator>("progress_indicator")->getVisible();
-}
-
-void LLFloaterEditDayCycle::onDeleteKey()
-{
- if (mSliderToKey.size() == 0)
- {
- return;
- }
- else if (mSliderToKey.size() == 1)
- {
- LLNotifications::instance().add("EnvCannotDeleteLastDayCycleKey", LLSD(), LLSD());
- return;
- }
-
- // delete from map
- const std::string& sldr_name = mKeysSlider->getCurSlider();
- std::map<std::string, SliderKey>::iterator mIt = mSliderToKey.find(sldr_name);
- mSliderToKey.erase(mIt);
-
- mKeysSlider->deleteCurSlider();
-
- if (mSliderToKey.size() == 0)
- {
- return;
- }
-
- const std::string& name = mKeysSlider->getCurSlider();
- mSkyPresetsCombo->selectByValue(mSliderToKey[name].keyframe.toStringVal());
- F32 time24 = mSliderToKey[name].time;
-
- mTimeCtrl->setTime24(time24);
-
- applyTrack();
-}
-
-void LLFloaterEditDayCycle::onRegionSettingsChange()
-{
- LL_DEBUGS("Windlight") << "Region settings changed" << LL_ENDL;
-
- if (getApplyProgress()) // our region settings have being applied
- {
- setApplyProgress(false);
-
- // Change preference if requested.
- if (mMakeDefaultCheckBox->getValue())
- {
- LL_DEBUGS("Windlight") << "Changed environment preference to region settings" << LL_ENDL;
- LLEnvManagerNew::instance().setUseRegionSettings(true);
- }
-
- closeFloater();
- }
-}
-
-void LLFloaterEditDayCycle::onRegionChange()
-{
- LL_DEBUGS("Windlight") << "Region changed" << LL_ENDL;
-
- // If we're editing the region day cycle
- if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
- {
- reset(); // undoes all unsaved changes
- }
-}
-
-void LLFloaterEditDayCycle::onRegionSettingsApplied(bool success)
-{
- LL_DEBUGS("Windlight") << "Region settings applied: " << success << LL_ENDL;
-
- if (!success)
- {
- // stop progress indicator
- setApplyProgress(false);
- }
-}
-
-void LLFloaterEditDayCycle::onRegionInfoUpdate()
-{
- LL_DEBUGS("Windlight") << "Region info updated" << LL_ENDL;
- bool can_edit = true;
-
- // If we've selected the region day cycle for editing.
- if (getSelectedDayCycle().scope == LLEnvKey::SCOPE_REGION)
- {
- // check whether we have the access
- can_edit = LLEnvManagerNew::canEditRegionSettings();
- }
-
- enableEditing(can_edit);
-}
-
-void LLFloaterEditDayCycle::onDayCycleNameEdited()
-{
- // Disable saving a day cycle having empty name.
- LLWLParamKey key = getSelectedDayCycle();
- mSaveButton->setEnabled(!key.name.empty());
-}
-
-void LLFloaterEditDayCycle::onDayCycleSelected()
-{
- LLSD day_data;
- LLWLParamKey dc_key = getSelectedDayCycle();
- bool can_edit = true;
-
- if (dc_key.scope == LLEnvKey::SCOPE_LOCAL)
- {
- if (!LLDayCycleManager::instance().getPreset(dc_key.name, day_data))
- {
- LL_WARNS() << "No day cycle named " << dc_key.name << LL_ENDL;
- return;
- }
- }
- else
- {
- day_data = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
- if (day_data.size() == 0)
- {
- LL_WARNS() << "Empty region day cycle" << LL_ENDL;
- llassert(day_data.size() > 0);
- return;
- }
-
- can_edit = LLEnvManagerNew::canEditRegionSettings();
- }
-
- // We may need to add or remove region skies from the list.
- refreshSkyPresetsList();
-
- F32 slider_time = mTimeSlider->getCurSliderValue() / sHoursPerDay;
- LLWLParamManager::instance().applyDayCycleParams(day_data, dc_key.scope, slider_time);
- loadTrack();
-
- enableEditing(can_edit);
-}
-
-void LLFloaterEditDayCycle::onBtnSave()
-{
- LLDayCycleManager& day_mgr = LLDayCycleManager::instance();
- LLWLParamKey selected_day = getSelectedDayCycle();
-
- if (selected_day.scope == LLEnvKey::SCOPE_REGION)
- {
- saveRegionDayCycle();
- closeFloater();
- return;
- }
-
- std::string name = selected_day.name;
- if (name.empty())
- {
- // *TODO: show an alert
- LL_WARNS() << "Empty day cycle name" << LL_ENDL;
- return;
- }
-
- // Don't allow overwriting system presets.
- if (day_mgr.isSystemPreset(name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- // Save, ask for confirmation for overwriting an existing preset.
- if (day_mgr.presetExists(name))
- {
- LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditDayCycle::onSaveAnswer, this, _1, _2));
- }
- else
- {
- // new preset, hence no confirmation needed
- onSaveConfirmed();
- }
-}
-
-void LLFloaterEditDayCycle::onBtnCancel()
-{
- closeFloater();
-}
-
-bool LLFloaterEditDayCycle::onSaveAnswer(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- // If they choose save, do it. Otherwise, don't do anything
- if (option == 0)
- {
- onSaveConfirmed();
- }
-
- return false;
-}
-
-void LLFloaterEditDayCycle::onSaveConfirmed()
-{
- std::string name = getSelectedDayCycle().name;
-
- // Save preset.
- LLSD data = LLWLParamManager::instance().mDay.asLLSD();
- LL_DEBUGS("Windlight") << "Saving day cycle " << name << ": " << data << LL_ENDL;
- LLDayCycleManager::instance().savePreset(name, data);
-
- // Change preference if requested.
- if (mMakeDefaultCheckBox->getValue())
- {
- LL_DEBUGS("Windlight") << name << " is now the new preferred day cycle" << LL_ENDL;
- LLEnvManagerNew::instance().setUseDayCycle(name);
- }
-
- closeFloater();
-}
-
-void LLFloaterEditDayCycle::onDayCycleListChange()
-{
- if (!isNewDay())
- {
- refreshDayCyclesList();
- }
-}
-
-void LLFloaterEditDayCycle::onSkyPresetListChange()
-{
- refreshSkyPresetsList();
-
- // Refresh sliders from the currently visible day cycle.
- loadTrack();
-}
-
-// static
-std::string LLFloaterEditDayCycle::getRegionName()
-{
- return gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
-}
diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h
deleted file mode 100644
index e6e4fe39c1..0000000000
--- a/indra/newview/llfloatereditdaycycle.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @file llfloatereditdaycycle.h
- * @brief Floater to create or edit a day cycle
- *
- * $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$
- */
-
-#ifndef LL_LLFLOATEREDITDAYCYCLE_H
-#define LL_LLFLOATEREDITDAYCYCLE_H
-
-#include "llfloater.h"
-
-#include "llwlparammanager.h" // for LLWLParamKey
-
-class LLCheckBoxCtrl;
-class LLComboBox;
-class LLLineEditor;
-class LLMultiSliderCtrl;
-class LLTimeCtrl;
-
-/**
- * Floater for creating or editing a day cycle.
- */
-class LLFloaterEditDayCycle : public LLFloater
-{
- LOG_CLASS(LLFloaterEditDayCycle);
-
-public:
- LLFloaterEditDayCycle(const LLSD &key);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
-
-private:
-
- /// sync the time slider with day cycle structure
- void syncTimeSlider();
-
- // makes sure key slider has what's in day cycle
- void loadTrack();
-
- /// makes sure day cycle data structure has what's in menu
- void applyTrack();
-
- /// refresh the sky presets combobox
- void refreshSkyPresetsList();
-
- /// refresh the day cycle combobox
- void refreshDayCyclesList();
-
- /// add a slider to the track
- void addSliderKey(F32 time, LLWLParamKey keyframe);
-
- void initCallbacks();
- LLWLParamKey getSelectedDayCycle();
- bool isNewDay() const;
- void dumpTrack();
- void enableEditing(bool enable);
- void reset();
- void saveRegionDayCycle();
-
- void setApplyProgress(bool started);
- bool getApplyProgress() const;
-
- void onTimeSliderMoved(); /// time slider moved
- void onKeyTimeMoved(); /// a key frame moved
- void onKeyTimeChanged(); /// a key frame's time changed
- void onKeyPresetChanged(); /// sky preset selected
- void onAddKey(); /// new key added on slider
- void onDeleteKey(); /// a key frame deleted
-
- void onRegionSettingsChange();
- void onRegionChange();
- void onRegionSettingsApplied(bool success);
- void onRegionInfoUpdate();
-
- void onDayCycleNameEdited();
- void onDayCycleSelected();
- void onBtnSave();
- void onBtnCancel();
-
- bool onSaveAnswer(const LLSD& notification, const LLSD& response);
- void onSaveConfirmed();
-
- void onDayCycleListChange();
- void onSkyPresetListChange();
-
- static std::string getRegionName();
-
- /// convenience class for holding keyframes mapped to sliders
- struct SliderKey
- {
- public:
- SliderKey(LLWLParamKey kf, F32 t) : keyframe(kf), time(t) {}
- SliderKey() : keyframe(), time(0.f) {} // Don't use this default constructor
-
- LLWLParamKey keyframe;
- F32 time;
- };
-
- static const F32 sHoursPerDay;
-
- LLLineEditor* mDayCycleNameEditor;
- LLComboBox* mDayCyclesCombo;
- LLMultiSliderCtrl* mTimeSlider;
- LLMultiSliderCtrl* mKeysSlider;
- LLComboBox* mSkyPresetsCombo;
- LLTimeCtrl* mTimeCtrl;
- LLCheckBoxCtrl* mMakeDefaultCheckBox;
- LLButton* mSaveButton;
-
- // map of sliders to parameters
- std::map<std::string, SliderKey> mSliderToKey;
-};
-
-#endif // LL_LLFLOATEREDITDAYCYCLE_H
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
new file mode 100644
index 0000000000..e888144b6a
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -0,0 +1,479 @@
+/**
+ * @file llfloatereditenvironmentbase.cpp
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditenvironmentbase.h"
+
+#include <boost/make_shared.hpp>
+
+// libs
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llfilepicker.h"
+#include "llsettingspicker.h"
+#include "llviewerparcelmgr.h"
+
+// newview
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+#include "llenvironment.h"
+#include "llagent.h"
+#include "llparcel.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+
+namespace
+{
+ const std::string ACTION_APPLY_LOCAL("apply_local");
+ const std::string ACTION_APPLY_PARCEL("apply_parcel");
+ const std::string ACTION_APPLY_REGION("apply_region");
+}
+
+//=========================================================================
+const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id");
+
+
+//=========================================================================
+
+class LLFixedSettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle<LLFloater> mHandle;
+};
+
+//=========================================================================
+LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) :
+ LLFloater(key),
+ mInventoryId(),
+ mInventoryItem(nullptr),
+ mIsDirty(false),
+ mCanCopy(false),
+ mCanMod(false),
+ mCanTrans(false),
+ mCanSave(false)
+{
+}
+
+LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase()
+{
+}
+
+void LLFloaterEditEnvironmentBase::onFocusReceived()
+{
+ if (isInVisibleChain())
+ {
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+ }
+}
+
+void LLFloaterEditEnvironmentBase::onFocusLost()
+{
+}
+
+void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID &inventoryId, bool can_trans)
+{
+ if (inventoryId.isNull())
+ {
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mCanMod = true;
+ mCanCopy = true;
+ mCanTrans = true;
+ return;
+ }
+
+ mInventoryId = inventoryId;
+ LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+ mInventoryItem = gInventory.getItem(mInventoryId);
+
+ if (!mInventoryItem)
+ {
+ LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
+ LLNotificationsUtil::add("CantFindInvItem");
+ closeFloater();
+
+ mInventoryId.setNull();
+ mInventoryItem = nullptr;
+ return;
+ }
+
+ if (mInventoryItem->getAssetUUID().isNull())
+ {
+ LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
+ LLNotificationsUtil::add("UnableEditItem");
+ closeFloater();
+
+ mInventoryId.setNull();
+ mInventoryItem = nullptr;
+ return;
+ }
+
+ mCanSave = true;
+ mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+ mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+ mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+ mExpectingAssetId = mInventoryItem->getAssetUUID();
+ LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+
+void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb)
+{
+ if (isDirty())
+ {
+ LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType())
+ ("NAME", getEditSettings()->getName()));
+
+ // create and show confirmation textbox
+ LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
+ [cb](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ cb();
+ });
+ }
+ else if (cb)
+ {
+ cb();
+ }
+}
+
+void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+ if (asset_id != mExpectingAssetId)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
+ return;
+ }
+ mExpectingAssetId.setNull();
+ clearDirtyFlag();
+
+ if (!settings || status)
+ {
+ LLSD args;
+ args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
+ LLNotificationsUtil::add("FailedToFindSettings", args);
+ closeFloater();
+ return;
+ }
+
+ if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
+ {
+ mCanSave = false;
+ mCanCopy = false;
+ mCanMod = false;
+ mCanTrans = false;
+ }
+ else
+ {
+ if (mInventoryItem)
+ settings->setName(mInventoryItem->getName());
+
+ if (mCanCopy)
+ settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
+
+ if (mCanMod)
+ settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOMOD);
+
+ if (mCanTrans)
+ settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
+ else
+ settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
+ }
+
+ setEditSettingsAndUpdate(settings);
+}
+
+void LLFloaterEditEnvironmentBase::onButtonImport()
+{
+ checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); });
+}
+
+void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ // Ideally notification should disable 'OK' button if name won't fit our requirements,
+ // for now either display notification, or use some default name
+ settings_name = "Unnamed";
+ }
+
+ if (mCanMod)
+ {
+ doApplyCreateNewInventory(settings_name, settings);
+ }
+ else if (mInventoryItem)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ if (marketplacelistings_id == parent_id)
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ }
+
+ LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
+ copy_inventory_item(
+ gAgent.getID(),
+ mInventoryItem->getPermissions().getOwner(),
+ mInventoryItem->getUUID(),
+ parent_id,
+ settings_name,
+ cb);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
+ }
+ }
+}
+
+void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
+ else
+ closeFloater();
+}
+
+void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings)
+{
+ if (mInventoryItem)
+ {
+ LLUUID parent_id = mInventoryItem->getParentUUID();
+ U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+ LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+ // This method knows what sort of settings object to create.
+ LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings)
+{
+ LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL;
+ if (mInventoryId.isNull())
+ {
+ LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+ }
+ else
+ {
+ LLSettingsVOBase::updateInventoryItem(settings, mInventoryId,
+ [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+ }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings)
+{
+ U32 flags(0);
+
+ if (mInventoryItem)
+ {
+ if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOMOD;
+ if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOTRANS;
+ }
+
+ flags |= settings->getFlags();
+ settings->setFlag(flags);
+
+ if (where == ACTION_APPLY_LOCAL)
+ {
+ settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings);
+ }
+ else if (where == ACTION_APPLY_PARCEL)
+ {
+ LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+ if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
+ {
+ LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL;
+ LLNotificationsUtil::add("WLParcelApplyFail");
+ return;
+ }
+
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+ }
+ else if (settings->getSettingsType() == "day")
+ {
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+ }
+ }
+ else if (where == ACTION_APPLY_REGION)
+ {
+ if (mInventoryItem && !isDirty())
+ {
+ LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+ }
+ else if (settings->getSettingsType() == "sky")
+ {
+ LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+ }
+ else if (settings->getSettingsType() == "day")
+ {
+ LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
+ return;
+ }
+
+}
+
+void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting)
+{
+ LLFloater* floaterp = mInventoryFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ if (inventory_id.isNull() || !results["success"].asBoolean())
+ {
+ LLNotificationsUtil::add("CantCreateInventory");
+ return;
+ }
+ onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
+ bool can_trans = true;
+ if (mInventoryItem)
+ {
+ LLPermissions perms = mInventoryItem->getPermissions();
+
+ LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+ if (created_item)
+ {
+ can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ created_item->setPermissions(perms);
+ created_item->updateServer(false);
+ }
+ }
+
+ clearDirtyFlag();
+ setFocus(TRUE); // Call back the focus...
+ loadInventoryItem(inventory_id, can_trans);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ clearDirtyFlag();
+ if (inventory_id != mInventoryId)
+ {
+ loadInventoryItem(inventory_id);
+ }
+}
+
+void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value)
+{
+ if (value)
+ setDirtyFlag();
+}
+
+//-------------------------------------------------------------------------
+bool LLFloaterEditEnvironmentBase::canUseInventory() const
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyRegion() const
+{
+ return gAgent.canManageEstate();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyParcel() const
+{
+ return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+}
+
+//=========================================================================
diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h
new file mode 100644
index 0000000000..7c7cf5bdcd
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.h
@@ -0,0 +1,148 @@
+/**
+ * @file llfloatereditenvironmentbase.h
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#ifndef LL_FLOATEREDITENVIRONMENTBASE_H
+#define LL_FLOATEREDITENVIRONMENTBASE_H
+
+#include "llfloater.h"
+#include "llsettingsbase.h"
+#include "llflyoutcombobtn.h"
+#include "llinventory.h"
+
+#include "boost/signals2.hpp"
+
+class LLTabContainer;
+class LLButton;
+class LLLineEditor;
+class LLFloaterSettingsPicker;
+class LLFixedSettingCopiedCallback;
+
+class LLFloaterEditEnvironmentBase : public LLFloater
+{
+ LOG_CLASS(LLFloaterEditEnvironmentBase);
+
+ friend class LLFixedSettingCopiedCallback;
+
+public:
+ static const std::string KEY_INVENTORY_ID;
+
+ LLFloaterEditEnvironmentBase(const LLSD &key);
+ ~LLFloaterEditEnvironmentBase();
+
+ virtual void onFocusReceived() override;
+ virtual void onFocusLost() override;
+
+ virtual LLSettingsBase::ptr_t getEditSettings() const = 0;
+
+ virtual BOOL isDirty() const override { return getIsDirty(); }
+
+protected:
+ typedef std::function<void()> on_confirm_fn;
+
+ virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0;
+ virtual void updateEditEnvironment() = 0;
+
+ virtual LLFloaterSettingsPicker *getSettingsPicker() = 0;
+
+ void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true);
+
+ void checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+ virtual void doImportFromDisk() = 0;
+ virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings);
+ virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings);
+ virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings);
+ void doCloseInventoryFloater(bool quitting = false);
+
+ bool canUseInventory() const;
+ bool canApplyRegion() const;
+ bool canApplyParcel() const;
+
+ LLUUID mInventoryId;
+ LLInventoryItem * mInventoryItem;
+ LLHandle<LLFloater> mInventoryFloater;
+ bool mCanCopy;
+ bool mCanMod;
+ bool mCanTrans;
+ bool mCanSave;
+
+ bool mIsDirty;
+
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+ bool getIsDirty() const { return mIsDirty; }
+ void setDirtyFlag() { mIsDirty = true; }
+ virtual void clearDirtyFlag() = 0;
+
+ void onPanelDirtyFlagChanged(bool);
+
+ virtual void onClickCloseBtn(bool app_quitting = false) override;
+ void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);
+ void onButtonImport();
+
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
+
+private:
+ LLUUID mExpectingAssetId; // for asset load confirmation
+};
+
+class LLSettingsEditPanel : public LLPanel
+{
+public:
+ virtual void setSettings(const LLSettingsBase::ptr_t &) = 0;
+
+ typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg;
+ typedef boost::signals2::connection connection_t;
+
+ inline bool getIsDirty() const { return mIsDirty; }
+ inline void setIsDirty() { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+ inline void clearIsDirty() { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+
+ inline bool getCanChangeSettings() const { return mCanEdit; }
+ inline void setCanChangeSettings(bool flag) { mCanEdit = flag; }
+
+ inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); }
+
+
+protected:
+ LLSettingsEditPanel() :
+ LLPanel(),
+ mIsDirty(false),
+ mOnDirtyChanged()
+ {}
+
+private:
+ void onTextureChanged(LLUUID &inventory_item_id);
+
+ bool mIsDirty;
+ bool mCanEdit;
+
+ on_dirty_charged_sg mOnDirtyChanged;
+};
+
+#endif // LL_FLOATERENVIRONMENTBASE_H
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
new file mode 100644
index 0000000000..0501c287ad
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -0,0 +1,1801 @@
+/**
+ * @file llfloatereditextdaycycle.cpp
+ * @brief Floater to create or edit a day cycle
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditextdaycycle.h"
+
+// libs
+#include "llbutton.h"
+#include "llcallbacklist.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llloadingindicator.h"
+#include "lllocalbitmaps.h"
+#include "llmultisliderctrl.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llspinctrl.h"
+#include "lltimectrl.h"
+#include "lltabcontainer.h"
+#include "llfilepicker.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+#include "llviewerparcelmgr.h"
+
+#include "llsettingspicker.h"
+#include "lltrackpicker.h"
+
+// newview
+#include "llagent.h"
+#include "llappviewer.h" //gDisconected
+#include "llparcel.h"
+#include "llflyoutcombobtn.h" //Todo: make a proper UI element/button/panel instead
+#include "llregioninfomodel.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
+#include "llviewerregion.h"
+#include "llpaneleditwater.h"
+#include "llpaneleditsky.h"
+
+#include "llui.h"
+
+#include "llenvironment.h"
+#include "lltrans.h"
+
+extern LLControlGroup gSavedSettings;
+
+//=========================================================================
+namespace {
+ const std::string track_tabs[] = {
+ "water_track",
+ "sky1_track",
+ "sky2_track",
+ "sky3_track",
+ "sky4_track",
+ };
+
+ const std::string ICN_LOCK_EDIT("icn_lock_edit");
+ const std::string BTN_SAVE("save_btn");
+ const std::string BTN_FLYOUT("btn_flyout");
+ const std::string BTN_CANCEL("cancel_btn");
+ const std::string BTN_ADDFRAME("add_frame");
+ const std::string BTN_DELFRAME("delete_frame");
+ const std::string BTN_IMPORT("btn_import");
+ const std::string BTN_LOADFRAME("btn_load_frame");
+ const std::string BTN_CLONETRACK("copy_track");
+ const std::string BTN_LOADTRACK("load_track");
+ const std::string BTN_CLEARTRACK("clear_track");
+ const std::string SLDR_TIME("WLTimeSlider");
+ const std::string SLDR_KEYFRAMES("WLDayCycleFrames");
+ const std::string VIEW_SKY_SETTINGS("frame_settings_sky");
+ const std::string VIEW_WATER_SETTINGS("frame_settings_water");
+ const std::string LBL_CURRENT_TIME("current_time");
+ const std::string TXT_DAY_NAME("day_cycle_name");
+ const std::string TABS_SKYS("sky_tabs");
+ const std::string TABS_WATER("water_tabs");
+
+ const std::string EVNT_DAYTRACK("DayCycle.Track");
+ const std::string EVNT_PLAY("DayCycle.PlayActions");
+
+ const std::string ACTION_PLAY("play");
+ const std::string ACTION_PAUSE("pause");
+ const std::string ACTION_FORWARD("forward");
+ const std::string ACTION_BACK("back");
+
+ // For flyout
+ const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
+ // From menu_save_settings.xml, consider moving into flyout since it should be supported by flyout either way
+ const std::string ACTION_SAVE("save_settings");
+ const std::string ACTION_SAVEAS("save_as_new_settings");
+ const std::string ACTION_COMMIT("commit_changes");
+ const std::string ACTION_APPLY_LOCAL("apply_local");
+ const std::string ACTION_APPLY_PARCEL("apply_parcel");
+ const std::string ACTION_APPLY_REGION("apply_region");
+
+ const F32 DAY_CYCLE_PLAY_TIME_SECONDS = 60;
+
+ const std::string STR_COMMIT_PARCEL("commit_parcel");
+ const std::string STR_COMMIT_REGION("commit_region");
+ //---------------------------------------------------------------------
+
+}
+
+//=========================================================================
+const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
+const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
+const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
+
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
+const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
+/*
+//=========================================================================
+
+class LLDaySettingCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLDaySettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mHandle.isDead())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item)
+ {
+ LLFloaterEditExtDayCycle* floater = (LLFloaterEditExtDayCycle*)mHandle.get();
+ floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+ }
+ }
+ }
+
+private:
+ LLHandle<LLFloater> mHandle;
+};*/
+
+//=========================================================================
+
+LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
+ LLFloaterEditEnvironmentBase(key),
+ mFlyoutControl(nullptr),
+ mDayLength(0),
+ mCurrentTrack(1),
+ mShiftCopyEnabled(false),
+ mTimeSlider(nullptr),
+ mFramesSlider(nullptr),
+ mCurrentTimeLabel(nullptr),
+ mImportButton(nullptr),
+ mLoadFrame(nullptr),
+ mSkyBlender(),
+ mWaterBlender(),
+ mScratchSky(),
+ mScratchWater(),
+ mIsPlaying(false),
+ mCloneTrack(nullptr),
+ mLoadTrack(nullptr),
+ mClearTrack(nullptr)
+{
+
+ mCommitCallbackRegistrar.add(EVNT_DAYTRACK, [this](LLUICtrl *ctrl, const LLSD &data) { onTrackSelectionCallback(data); });
+ mCommitCallbackRegistrar.add(EVNT_PLAY, [this](LLUICtrl *ctrl, const LLSD &data) { onPlayActionCallback(data); });
+
+ mScratchSky = LLSettingsVOSky::buildDefaultSky();
+ mScratchWater = LLSettingsVOWater::buildDefaultWater();
+
+ mEditSky = mScratchSky;
+ mEditWater = mScratchWater;
+}
+
+LLFloaterEditExtDayCycle::~LLFloaterEditExtDayCycle()
+{
+ // Todo: consider remaking mFlyoutControl into full view class that initializes intself with floater,
+ // complete with postbuild, e t c...
+ delete mFlyoutControl;
+}
+
+// virtual
+BOOL LLFloaterEditExtDayCycle::postBuild()
+{
+ getChild<LLLineEditor>(TXT_DAY_NAME)->setKeystrokeCallback(boost::bind(&LLFloaterEditExtDayCycle::onCommitName, this, _1, _2), NULL);
+
+ mAddFrameButton = getChild<LLButton>(BTN_ADDFRAME, true);
+ mDeleteFrameButton = getChild<LLButton>(BTN_DELFRAME, true);
+ mTimeSlider = getChild<LLMultiSliderCtrl>(SLDR_TIME);
+ mFramesSlider = getChild<LLMultiSliderCtrl>(SLDR_KEYFRAMES);
+ mSkyTabLayoutContainer = getChild<LLView>(VIEW_SKY_SETTINGS, true);
+ mWaterTabLayoutContainer = getChild<LLView>(VIEW_WATER_SETTINGS, true);
+ mCurrentTimeLabel = getChild<LLTextBox>(LBL_CURRENT_TIME, true);
+ mImportButton = getChild<LLButton>(BTN_IMPORT, true);
+ mLoadFrame = getChild<LLButton>(BTN_LOADFRAME, true);
+ mCloneTrack = getChild<LLButton>(BTN_CLONETRACK, true);
+ mLoadTrack = getChild<LLButton>(BTN_LOADTRACK, true);
+ mClearTrack = getChild<LLButton>(BTN_CLEARTRACK, true);
+
+ mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BTN_SAVE, BTN_FLYOUT, XML_FLYOUTMENU_FILE, false);
+ mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); });
+
+ getChild<LLButton>(BTN_CANCEL, true)->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onClickCloseBtn(); });
+ mTimeSlider->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onTimeSliderCallback(); });
+ mAddFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onAddFrame(); });
+ mDeleteFrameButton->setCommitCallback([this](LLUICtrl *ctrl, const LLSD &data) { onRemoveFrame(); });
+ mImportButton->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonImport(); });
+ mLoadFrame->setCommitCallback([this](LLUICtrl *, const LLSD &){ onButtonLoadFrame(); });
+
+ mCloneTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onCloneTrack(); });
+ mLoadTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onLoadTrack();});
+ mClearTrack->setCommitCallback([this](LLUICtrl *, const LLSD&){ onClearTrack(); });
+
+
+ mFramesSlider->setCommitCallback([this](LLUICtrl *, const LLSD &data) { onFrameSliderCallback(data); });
+ mFramesSlider->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderDoubleClick(x, y, mask); });
+ mFramesSlider->setMouseDownCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseDown(x, y, mask); });
+ mFramesSlider->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask){ onFrameSliderMouseUp(x, y, mask); });
+
+ mTimeSlider->addSlider(0);
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ LLSettingsEditPanel *panel = nullptr;
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool val) { onPanelDirtyFlagChanged(val); });
+ }
+
+ return TRUE;
+}
+
+void LLFloaterEditExtDayCycle::onOpen(const LLSD& key)
+{
+ if (!mEditDay)
+ {
+ LLEnvironment::instance().saveBeaconsState();
+ }
+ mEditDay.reset();
+ mEditContext = CONTEXT_UNKNOWN;
+ if (key.has(KEY_EDIT_CONTEXT))
+ {
+ std::string context = key[KEY_EDIT_CONTEXT].asString();
+
+ if (context == VALUE_CONTEXT_INVENTORY)
+ mEditContext = CONTEXT_INVENTORY;
+ else if (context == VALUE_CONTEXT_PARCEL)
+ mEditContext = CONTEXT_PARCEL;
+ else if (context == VALUE_CONTEXT_REGION)
+ mEditContext = CONTEXT_REGION;
+ }
+
+ if (key.has(KEY_CANMOD))
+ {
+ mCanMod = key[KEY_CANMOD].asBoolean();
+ }
+
+ if (mEditContext == CONTEXT_UNKNOWN)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown editing context!" << LL_ENDL;
+ }
+
+ if (key.has(KEY_INVENTORY_ID))
+ {
+ loadInventoryItem(key[KEY_INVENTORY_ID].asUUID());
+ }
+ else
+ {
+ mCanSave = true;
+ mCanCopy = true;
+ mCanMod = true;
+ mCanTrans = true;
+ setEditDefaultDayCycle();
+ }
+
+ mDayLength.value(0);
+ if (key.has(KEY_DAY_LENGTH))
+ {
+ mDayLength.value(key[KEY_DAY_LENGTH].asReal());
+ }
+
+ // Time&Percentage labels
+ mCurrentTimeLabel->setTextArg("[PRCNT]", std::string("0"));
+ const S32 max_elm = 5;
+ if (mDayLength.value() != 0)
+ {
+ S32Hours hrs;
+ S32Minutes minutes;
+ LLSettingsDay::Seconds total;
+ LLUIString formatted_label = getString("time_label");
+ for (int i = 0; i < max_elm; i++)
+ {
+ total = ((mDayLength / (max_elm - 1)) * i);
+ hrs = total;
+ minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", formatted_label.getString());
+ }
+ hrs = mDayLength;
+ minutes = mDayLength - hrs;
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ for (int i = 0; i < max_elm; i++)
+ {
+ getChild<LLTextBox>("p" + llformat("%d", i), true)->setTextArg("[DSC]", std::string());
+ }
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Adjust Time&Percentage labels' location according to length
+ LLRect label_rect = getChild<LLTextBox>("p0", true)->getRect();
+ F32 slider_width = mFramesSlider->getRect().getWidth();
+ for (int i = 1; i < max_elm; i++)
+ {
+ LLTextBox *pcnt_label = getChild<LLTextBox>("p" + llformat("%d", i), true);
+ LLRect new_rect = pcnt_label->getRect();
+ new_rect.mLeft = label_rect.mLeft + (S32)(slider_width * (F32)i / (F32)(max_elm - 1)) - (S32)(pcnt_label->getTextPixelWidth() / 2);
+ pcnt_label->setRect(new_rect);
+ }
+
+ // Altitudes&Track labels
+ LLUIString formatted_label = getString("sky_track_label");
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ bool use_altitudes = extended_env
+ && altitudes.size() > 0
+ && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ for (S32 idx = 1; idx < 4; ++idx)
+ {
+ std::ostringstream convert;
+ if (use_altitudes)
+ {
+ convert << altitudes[idx] << "m";
+ }
+ else
+ {
+ convert << (idx + 1);
+ }
+ formatted_label.setArg("[ALT]", convert.str());
+ getChild<LLButton>(track_tabs[idx + 1], true)->setLabel(formatted_label.getString());
+ }
+
+ for (U32 i = 2; i < LLSettingsDay::TRACK_MAX; i++) //skies #2 through #4
+ {
+ getChild<LLButton>(track_tabs[i])->setEnabled(extended_env);
+ }
+
+ if (mEditContext == CONTEXT_INVENTORY)
+ {
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_SAVE);
+ }
+ else if ((mEditContext == CONTEXT_REGION) || (mEditContext == CONTEXT_PARCEL))
+ {
+ std::string commit_str = (mEditContext == CONTEXT_PARCEL) ? STR_COMMIT_PARCEL : STR_COMMIT_REGION;
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, getString(commit_str));
+ mFlyoutControl->setShownBtnEnabled(true);
+ mFlyoutControl->setSelectedItem(ACTION_COMMIT);
+ }
+ else
+ {
+ mFlyoutControl->setShownBtnEnabled(false);
+ }
+}
+
+void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
+{
+ doCloseInventoryFloater(app_quitting);
+ doCloseTrackFloater(app_quitting);
+ // there's no point to change environment if we're quitting
+ // or if we already restored environment
+ stopPlay();
+ LLEnvironment::instance().revertBeaconsState();
+ if (!app_quitting)
+ {
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_FAST);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ mEditDay.reset();
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)
+{
+}
+
+void LLFloaterEditExtDayCycle::refresh()
+{
+ if (mEditDay)
+ {
+ LLLineEditor* name_field = getChild<LLLineEditor>(TXT_DAY_NAME);
+ name_field->setText(mEditDay->getName());
+ name_field->setEnabled(mCanMod);
+ }
+
+
+ bool is_inventory_avail = canUseInventory();
+
+ bool show_commit = ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+ bool show_apply = (mEditContext == CONTEXT_INVENTORY);
+
+ if (show_commit)
+ {
+ std::string commit_text;
+ if (mEditContext == CONTEXT_PARCEL)
+ commit_text = getString(STR_COMMIT_PARCEL);
+ else
+ commit_text = getString(STR_COMMIT_REGION);
+
+ mFlyoutControl->setMenuItemLabel(ACTION_COMMIT, commit_text);
+ }
+
+ mFlyoutControl->setMenuItemVisible(ACTION_COMMIT, show_commit);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVE, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_SAVEAS, is_inventory_avail);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_PARCEL, show_apply);
+ mFlyoutControl->setMenuItemVisible(ACTION_APPLY_REGION, show_apply);
+
+ mFlyoutControl->setMenuItemEnabled(ACTION_COMMIT, show_commit && !mCommitSignal.empty());
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail && mCanMod && !mInventoryId.isNull() && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy && mCanSave);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_LOCAL, true);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_PARCEL, canApplyParcel() && show_apply);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion() && show_apply);
+
+ mImportButton->setEnabled(mCanMod);
+
+ LLFloater::refresh();
+}
+
+void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+ setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+}
+
+void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
+{
+ mExpectingAssetId.setNull();
+ mEditDay = pday->buildDeepCloneAndUncompress();
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_WATER))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No water frames found, generating replacement" << LL_ENDL;
+ mEditDay->setWaterAtKeyframe(LLSettingsVOWater::buildDefaultWater(), .5f);
+ }
+
+ if (mEditDay->isTrackEmpty(LLSettingsDay::TRACK_GROUND_LEVEL))
+ {
+ LL_WARNS("ENVDAYEDIT") << "No sky frames found, generating replacement" << LL_ENDL;
+ mEditDay->setSkyAtKeyframe(LLSettingsVOSky::buildDefaultSky(), .5f, LLSettingsDay::TRACK_GROUND_LEVEL);
+ }
+
+ mCanSave = !pday->getFlag(LLSettingsBase::FLAG_NOSAVE);
+ mCanCopy = !pday->getFlag(LLSettingsBase::FLAG_NOCOPY) && mCanSave;
+ mCanMod = !pday->getFlag(LLSettingsBase::FLAG_NOMOD) && mCanSave;
+ mCanTrans = !pday->getFlag(LLSettingsBase::FLAG_NOTRANS) && mCanSave;
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+
+void LLFloaterEditExtDayCycle::setEditDefaultDayCycle()
+{
+ mInventoryItem = nullptr;
+ mInventoryId.setNull();
+ mExpectingAssetId = LLSettingsDay::GetDefaultAssetId();
+ LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
+ [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+std::string LLFloaterEditExtDayCycle::getEditName() const
+{
+ if (mEditDay)
+ return mEditDay->getName();
+ return "new";
+}
+
+void LLFloaterEditExtDayCycle::setEditName(const std::string &name)
+{
+ if (mEditDay)
+ mEditDay->setName(name);
+ getChild<LLLineEditor>(TXT_DAY_NAME)->setText(name);
+}
+
+/* virtual */
+BOOL LLFloaterEditExtDayCycle::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent)
+{
+ if (!mEditDay)
+ {
+ mShiftCopyEnabled = false;
+ }
+ else if (mask == MASK_SHIFT && mShiftCopyEnabled)
+ {
+ mShiftCopyEnabled = false;
+ std::string curslider = mFramesSlider->getCurSlider();
+ if (!curslider.empty())
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos))
+ {
+ (*it).second.mFrame = sliderpos;
+ }
+ else
+ {
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Failed to find frame " << sliderpos << " for slider " << curslider << LL_ENDL;
+ }
+ }
+ }
+ return LLFloater::handleKeyUp(key, mask, called_from_parent);
+}
+
+void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
+{
+ std::string ctrl_action = ctrl->getName();
+
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "mEditDay is null! This should never happen! Something is very very wrong" << LL_ENDL;
+ LLNotificationsUtil::add("EnvironmentApplyFailed");
+ closeFloater();
+ return;
+ }
+
+ LLSettingsDay::ptr_t dayclone = mEditDay->buildClone(); // create a compressed copy
+
+ if (!dayclone)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unable to clone daycylce from editor." << LL_ENDL;
+ return;
+ }
+
+ // brute-force local texture scan
+ for (U32 i = 0; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = dayclone->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+ S32 frame_num = 0;
+
+ while (iter != end)
+ {
+ frame_num++;
+ std::string desc;
+ bool is_local = false; // because getString can be empty
+ if (i == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWater::ptr_t water = std::static_pointer_cast<LLSettingsWater>(iter->second);
+ if (water)
+ {
+ // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr
+ if (LLLocalBitmapMgr::getInstance()->isLocal(water->getNormalMapID()))
+ {
+ desc = LLTrans::getString("EnvironmentNormalMap");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(water->getTransparentTextureID()))
+ {
+ desc = LLTrans::getString("EnvironmentTransparent");
+ is_local = true;
+ }
+ }
+ }
+ else
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
+ if (sky)
+ {
+ if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getSunTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentSun");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getMoonTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentMoon");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getCloudNoiseTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentCloudNoise");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getBloomTextureId()))
+ {
+ desc = LLTrans::getString("EnvironmentBloom");
+ is_local = true;
+ }
+ }
+ }
+
+ if (is_local)
+ {
+ LLSD args;
+ LLButton* button = getChild<LLButton>(track_tabs[i], true);
+ args["TRACK"] = button->getCurrentLabel();
+ args["FRAME"] = iter->first * 100; // %
+ args["FIELD"] = desc;
+ args["FRAMENO"] = frame_num;
+ LLNotificationsUtil::add("WLLocalTextureDayBlock", args);
+ return;
+ }
+ iter++;
+ }
+ }
+
+ if (ctrl_action == ACTION_SAVE)
+ {
+ doApplyUpdateInventory(dayclone);
+ }
+ else if (ctrl_action == ACTION_SAVEAS)
+ {
+ LLSD args;
+ args["DESC"] = dayclone->getName();
+ LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterEditExtDayCycle::onSaveAsCommit, this, _1, _2, dayclone));
+ }
+ else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
+ (ctrl_action == ACTION_APPLY_PARCEL) ||
+ (ctrl_action == ACTION_APPLY_REGION))
+ {
+ doApplyEnvironment(ctrl_action, dayclone);
+ }
+ else if (ctrl_action == ACTION_COMMIT)
+ {
+ doApplyCommit(dayclone);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterEditExtDayCycle::onButtonLoadFrame()
+{
+ doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
+}
+
+void LLFloaterEditExtDayCycle::onAddFrame()
+{
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ LLSettingsBase::ptr_t setting;
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame too close to existing frame." << LL_ENDL;
+ return;
+ }
+ if (!mFramesSlider->canAddSliders())
+ {
+ // Shouldn't happen, button should be disabled
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ // scratch water should always have the current water settings.
+ LLSettingsWater::ptr_t water(mScratchWater->buildClone());
+ setting = water;
+ mEditDay->setWaterAtKeyframe( std::static_pointer_cast<LLSettingsWater>(setting), frame);
+ }
+ else
+ {
+ // scratch sky should always have the current sky settings.
+ LLSettingsSky::ptr_t sky(mScratchSky->buildClone());
+ setting = sky;
+ mEditDay->setSkyAtKeyframe(sky, frame, mCurrentTrack);
+ }
+ setDirtyFlag();
+ addSliderFrame(frame, setting);
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::onRemoveFrame()
+{
+ std::string sldr_key = mFramesSlider->getCurSlider();
+ if (sldr_key.empty())
+ {
+ return;
+ }
+ setDirtyFlag();
+ removeCurrentSliderFrame();
+ updateTabs();
+}
+
+
+void LLFloaterEditExtDayCycle::onCloneTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to copy track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+ const LLEnvironment::altitude_list_t &altitudes = LLEnvironment::instance().getRegionAltitudes();
+ bool use_altitudes = altitudes.size() > 0 && ((mEditContext == CONTEXT_PARCEL) || (mEditContext == CONTEXT_REGION));
+
+ LLSD args = LLSD::emptyArray();
+
+ S32 populated_counter = 0;
+ for (U32 i = 1; i < LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSD track;
+ track["id"] = LLSD::Integer(i);
+ bool populated = (!mEditDay->isTrackEmpty(i)) && (i != mCurrentTrack);
+ track["enabled"] = populated;
+ if (populated)
+ {
+ populated_counter++;
+ }
+ if (use_altitudes)
+ {
+ track["altitude"] = altitudes[i - 1];
+ }
+ args.append(track);
+ }
+
+ if (populated_counter > 0)
+ {
+ doOpenTrackFloater(args);
+ }
+ else
+ {
+ // Should not happen
+ LL_WARNS("ENVDAYEDIT") << "Tried to copy tracks, but there are no available sources" << LL_ENDL;
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::onLoadTrack()
+{
+ LLUUID curitemId = mInventoryId;
+
+ if (mCurrentEdit && curitemId.notNull())
+ {
+ curitemId = LLFloaterSettingsPicker::findItemID(mCurrentEdit->getAssetId(), false, false);
+ }
+
+ doOpenInventoryFloater(LLSettingsType::ST_DAYCYCLE, curitemId);
+}
+
+
+void LLFloaterEditExtDayCycle::onClearTrack()
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to clear track while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ if (mCurrentTrack > 1)
+ mEditDay->getCycleTrack(mCurrentTrack).clear();
+ else
+ {
+ LLSettingsDay::CycleTrack_t &track(mEditDay->getCycleTrack(mCurrentTrack));
+
+ auto first = track.begin();
+ auto last = track.end();
+ ++first;
+ track.erase(first, last);
+ }
+
+ updateEditEnvironment();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+ synchronizeTabs();
+ updateTabs();
+ refresh();
+}
+
+void LLFloaterEditExtDayCycle::onCommitName(class LLLineEditor* caller, void* user_data)
+{
+ if (!mEditDay)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to rename day while waiting for day(asset) to load." << LL_ENDL;
+ return;
+ }
+
+ mEditDay->setName(caller->getText());
+}
+
+void LLFloaterEditExtDayCycle::onTrackSelectionCallback(const LLSD& user_data)
+{
+ U32 track_index = user_data.asInteger(); // 1-5
+ selectTrack(track_index);
+}
+
+void LLFloaterEditExtDayCycle::onPlayActionCallback(const LLSD& user_data)
+{
+ std::string action = user_data.asString();
+
+ F32 frame = mTimeSlider->getCurSliderValue();
+
+ if (action == ACTION_PLAY)
+ {
+ startPlay();
+ }
+ else if (action == ACTION_PAUSE)
+ {
+ stopPlay();
+ }
+ else if (mSliderKeyMap.size() != 0)
+ {
+ F32 new_frame = 0;
+ if (action == ACTION_FORWARD)
+ {
+ new_frame = mEditDay->getUpperBoundFrame(mCurrentTrack, frame + (mTimeSlider->getIncrement() / 2));
+ }
+ else if (action == ACTION_BACK)
+ {
+ new_frame = mEditDay->getLowerBoundFrame(mCurrentTrack, frame - (mTimeSlider->getIncrement() / 2));
+ }
+ selectFrame(new_frame, 0.0f);
+ stopPlay();
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderCallback(const LLSD &data)
+{
+ std::string curslider = mFramesSlider->getCurSlider();
+
+ if (!curslider.empty() && mEditDay)
+ {
+ F32 sliderpos = mFramesSlider->getCurSliderValue();
+
+ keymap_t::iterator it = mSliderKeyMap.find(curslider);
+ if (it != mSliderKeyMap.end())
+ {
+ if (gKeyboard->currentMask(TRUE) == MASK_SHIFT && mShiftCopyEnabled && mCanMod)
+ {
+ // don't move the point/frame as long as shift is pressed and user is attempting to copy
+ // handleKeyUp will do the move if user releases key too early.
+ if (!(mEditDay->getSettingsNearKeyframe(sliderpos, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Copying frame from " << it->second.mFrame << " to " << sliderpos << LL_ENDL;
+ LLSettingsBase::ptr_t new_settings;
+
+ // mEditDay still remembers old position, add copy at new position
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ LLSettingsWaterPtr_t water_ptr = std::dynamic_pointer_cast<LLSettingsWater>(it->second.pSettings)->buildClone();
+ mEditDay->setWaterAtKeyframe(water_ptr, sliderpos);
+ new_settings = water_ptr;
+ }
+ else
+ {
+ LLSettingsSkyPtr_t sky_ptr = std::dynamic_pointer_cast<LLSettingsSky>(it->second.pSettings)->buildClone();
+ mEditDay->setSkyAtKeyframe(sky_ptr, sliderpos, mCurrentTrack);
+ new_settings = sky_ptr;
+ }
+ // mSliderKeyMap still remembers old position, for simplicity, just move it to be identical to slider
+ F32 old_frame = it->second.mFrame;
+ it->second.mFrame = sliderpos;
+ // slider already moved old frame, create new one in old place
+ addSliderFrame(old_frame, new_settings, false /*because we are going to reselect new one*/);
+ // reselect new frame
+ mFramesSlider->setCurSlider(it->first);
+ mShiftCopyEnabled = false;
+ setDirtyFlag();
+ }
+ }
+ else
+ {
+ // slider rounds values to nearest increments, changes can be substanntial (half increment)
+ if (abs(mFramesSlider->getNearestIncrement((*it).second.mFrame) - sliderpos) < F_APPROXIMATELY_ZERO)
+ {
+ // same value
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+ else if (mEditDay->moveTrackKeyframe(mCurrentTrack, (*it).second.mFrame, sliderpos) && mCanMod)
+ {
+ (*it).second.mFrame = sliderpos;
+ setDirtyFlag();
+ }
+ else
+ {
+ // same value, wrong track, no such value, no mod
+ mFramesSlider->setCurSliderValue((*it).second.mFrame);
+ }
+
+ mShiftCopyEnabled = false;
+ }
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderDoubleClick(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ onAddFrame();
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseDown(S32 x, S32 y, MASK mask)
+{
+ stopPlay();
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ std::string slidername = mFramesSlider->getCurSlider();
+
+ mShiftCopyEnabled = !slidername.empty() && gKeyboard->currentMask(TRUE) == MASK_SHIFT;
+
+ if (!slidername.empty())
+ {
+ LLRect thumb_rect = mFramesSlider->getSliderThumbRect(slidername);
+ if ((x >= thumb_rect.mRight) || (x <= thumb_rect.mLeft))
+ {
+ mFramesSlider->resetCurSlider();
+ }
+ }
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+
+ updateTabs();
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
+{
+ // Only happens when clicking on empty space of frameslider, not on specific frame
+ F32 sliderpos = mFramesSlider->getSliderValueFromPos(x, y);
+
+ mTimeSlider->setCurSliderValue(sliderpos);
+ selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::onTimeSliderCallback()
+{
+ stopPlay();
+ selectFrame(mTimeSlider->getCurSliderValue(), LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(U32 source_index, U32 dest_index)
+{
+ cloneTrack(mEditDay, source_index, dest_index);
+}
+
+void LLFloaterEditExtDayCycle::cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index)
+{
+ if ((source_index == LLSettingsDay::TRACK_WATER || dest_index == LLSettingsDay::TRACK_WATER) && (source_index != dest_index))
+ { // one of the tracks is a water track, the other is not
+ LLSD args;
+
+ LL_WARNS() << "Can not import water track into sky track or vice versa" << LL_ENDL;
+
+ LLButton* button = getChild<LLButton>(track_tabs[source_index], true);
+ args["TRACK1"] = button->getCurrentLabel();
+ button = getChild<LLButton>(track_tabs[dest_index], true);
+ args["TRACK2"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadMismatch", args);
+ return;
+ }
+
+ // don't use replaceCycleTrack because we will end up with references, but we need to clone
+
+ // hold on to a backup of the
+ LLSettingsDay::CycleTrack_t backup_track = mEditDay->getCycleTrack(dest_index);
+
+ mEditDay->clearCycleTrack(dest_index); // because source can be empty
+ LLSettingsDay::CycleTrack_t source_track = source_day->getCycleTrack(source_index);
+ S32 addcount(0);
+ for (auto &track_frame : source_track)
+ {
+ LLSettingsBase::ptr_t pframe = track_frame.second;
+ LLSettingsBase::ptr_t pframeclone = pframe->buildDerivedClone();
+ if (pframeclone)
+ {
+ ++addcount;
+ mEditDay->setSettingsAtKeyframe(pframeclone, track_frame.first, dest_index);
+ }
+ }
+
+ if (!addcount)
+ { // nothing was actually added. Restore the old track and issue a warning.
+ mEditDay->replaceCycleTrack(dest_index, backup_track);
+
+ LLSD args;
+ LLButton* button = getChild<LLButton>(track_tabs[dest_index], true);
+ args["TRACK"] = button->getCurrentLabel();
+
+ LLNotificationsUtil::add("TrackLoadFailed", args);
+ }
+ setDirtyFlag();
+
+ updateSlider();
+ updateTabs();
+ updateButtons();
+}
+
+void LLFloaterEditExtDayCycle::selectTrack(U32 track_index, bool force )
+{
+ if (track_index < LLSettingsDay::TRACK_MAX)
+ mCurrentTrack = track_index;
+
+ LLButton* button = getChild<LLButton>(track_tabs[mCurrentTrack], true);
+ if (button->getToggleState() && !force)
+ {
+ return;
+ }
+
+ for (U32 i = 0; i < LLSettingsDay::TRACK_MAX; i++) // use max value
+ {
+ getChild<LLButton>(track_tabs[i], true)->setToggleState(i == mCurrentTrack);
+ }
+
+ bool show_water = (mCurrentTrack == LLSettingsDay::TRACK_WATER);
+ mSkyTabLayoutContainer->setVisible(!show_water);
+ mWaterTabLayoutContainer->setVisible(show_water);
+
+ updateSlider();
+ updateLabels();
+}
+
+void LLFloaterEditExtDayCycle::selectFrame(F32 frame, F32 slop_factor)
+{
+ mFramesSlider->resetCurSlider();
+
+ keymap_t::iterator iter = mSliderKeyMap.begin();
+ keymap_t::iterator end_iter = mSliderKeyMap.end();
+ while (iter != end_iter)
+ {
+ F32 keyframe = iter->second.mFrame;
+ F32 frame_dif = fabs(keyframe - frame);
+ if (frame_dif <= slop_factor)
+ {
+ keymap_t::iterator next_iter = std::next(iter);
+ if ((frame_dif != 0) && (next_iter != end_iter))
+ {
+ if (fabs(next_iter->second.mFrame - frame) < frame_dif)
+ {
+ mFramesSlider->setCurSlider(next_iter->first);
+ frame = next_iter->second.mFrame;
+ break;
+ }
+ }
+ mFramesSlider->setCurSlider(iter->first);
+ frame = iter->second.mFrame;
+ break;
+ }
+ iter++;
+ }
+
+ mTimeSlider->setCurSliderValue(frame);
+ // block or update tabs according to new selection
+ updateTabs();
+// LLEnvironment::instance().updateEnvironment();
+}
+
+void LLFloaterEditExtDayCycle::clearTabs()
+{
+ // Note: If this doesn't look good, init panels with default settings. It might be better looking
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ const LLSettingsWaterPtr_t p_water = LLSettingsWaterPtr_t(NULL);
+ updateWaterTabs(p_water);
+ }
+ else
+ {
+ const LLSettingsSkyPtr_t p_sky = LLSettingsSkyPtr_t(NULL);
+ updateSkyTabs(p_sky);
+ }
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateTabs()
+{
+ reblendSettings();
+ synchronizeTabs();
+
+ updateButtons();
+ updateTimeAndLabel();
+}
+
+void LLFloaterEditExtDayCycle::updateWaterTabs(const LLSettingsWaterPtr_t &p_water)
+{
+ LLView* tab_container = mWaterTabLayoutContainer->getChild<LLView>(TABS_WATER); //can't extract panels directly, since it is in 'tuple'
+ LLPanelSettingsWaterMainTab* panel = dynamic_cast<LLPanelSettingsWaterMainTab*>(tab_container->findChildView("water_panel"));
+ if (panel)
+ {
+ panel->setWater(p_water);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky)
+{
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS); //can't extract panels directly, since they are in 'tuple'
+
+ LLPanelSettingsSky* panel;
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("atmosphere_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("clouds_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+ panel = dynamic_cast<LLPanelSettingsSky*>(tab_container->findChildView("moon_panel"));
+ if (panel)
+ {
+ panel->setSky(p_sky);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateLabels()
+{
+ std::string label_arg = (mCurrentTrack == LLSettingsDay::TRACK_WATER) ? "water_label" : "sky_label";
+
+ mAddFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mDeleteFrameButton->setLabelArg("[FRAME]", getString(label_arg));
+ mLoadFrame->setLabelArg("[FRAME]", getString(label_arg));
+}
+
+void LLFloaterEditExtDayCycle::updateButtons()
+{
+ // This logic appears to work in reverse, the add frame button
+ // is only enabled when you're on an existing frame and disabled
+ // in all the interim positions where you'd want to add a frame...
+
+ bool can_manipulate = mEditDay && !mIsPlaying && mCanMod;
+ bool can_clone(false);
+ bool can_clear(false);
+
+ if (can_manipulate)
+ {
+ if (mCurrentTrack == 0)
+ {
+ can_clone = false;
+ }
+ else
+ {
+ for (S32 track = 1; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ if (track == mCurrentTrack)
+ continue;
+ can_clone |= !mEditDay->getCycleTrack(track).empty();
+ }
+ }
+
+ can_clear = (mCurrentTrack > 1) ? (!mEditDay->getCycleTrack(mCurrentTrack).empty()) : (mEditDay->getCycleTrack(mCurrentTrack).size() > 1);
+ }
+
+ mCloneTrack->setEnabled(can_clone);
+ mLoadTrack->setEnabled(can_manipulate);
+ mClearTrack->setEnabled(can_clear);
+ mAddFrameButton->setEnabled(can_manipulate && isAddingFrameAllowed());
+ mDeleteFrameButton->setEnabled(can_manipulate && isRemovingFrameAllowed());
+ mLoadFrame->setEnabled(can_manipulate);
+
+ // update track buttons
+ bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ for (S32 track = 0; track < LLSettingsDay::TRACK_MAX; ++track)
+ {
+ LLButton* button = getChild<LLButton>(track_tabs[track], true);
+ button->setEnabled(extended_env);
+ button->setToggleState(track == mCurrentTrack);
+ }
+}
+
+void LLFloaterEditExtDayCycle::updateSlider()
+{
+ F32 frame_position = mTimeSlider->getCurSliderValue();
+ mFramesSlider->clear();
+ mSliderKeyMap.clear();
+
+ if (!mEditDay)
+ {
+ // floater is waiting for asset
+ return;
+ }
+
+ LLSettingsDay::CycleTrack_t track = mEditDay->getCycleTrack(mCurrentTrack);
+ for (auto &track_frame : track)
+ {
+ addSliderFrame(track_frame.first, track_frame.second, false);
+ }
+
+ if (mSliderKeyMap.size() > 0)
+ {
+ // update positions
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ }
+ else
+ {
+ // disable panels
+ clearTabs();
+ mLastFrameSlider.clear();
+ }
+
+ selectFrame(frame_position, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+}
+
+void LLFloaterEditExtDayCycle::updateTimeAndLabel()
+{
+ F32 time = mTimeSlider->getCurSliderValue();
+ mCurrentTimeLabel->setTextArg("[PRCNT]", llformat("%.0f", time * 100));
+ if (mDayLength.value() != 0)
+ {
+ LLUIString formatted_label = getString("time_label");
+
+ LLSettingsDay::Seconds total = (mDayLength * time);
+ S32Hours hrs = total;
+ S32Minutes minutes = total - hrs;
+
+ formatted_label.setArg("[HH]", llformat("%d", hrs.value()));
+ formatted_label.setArg("[MM]", llformat("%d", abs(minutes.value())));
+ mCurrentTimeLabel->setTextArg("[DSC]", formatted_label.getString());
+ }
+ else
+ {
+ mCurrentTimeLabel->setTextArg("[DSC]", std::string());
+ }
+
+ // Update blender here:
+}
+
+void LLFloaterEditExtDayCycle::addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui)
+{
+ // multi slider distinguishes elements by key/name in string format
+ // store names to map to be able to recall dependencies
+ std::string new_slider = mFramesSlider->addSlider(frame);
+ if (!new_slider.empty())
+ {
+ mSliderKeyMap[new_slider] = FrameData(frame, setting);
+
+ if (update_ui)
+ {
+ mLastFrameSlider = new_slider;
+ mTimeSlider->setCurSliderValue(frame);
+ updateTabs();
+ }
+ }
+}
+
+void LLFloaterEditExtDayCycle::removeCurrentSliderFrame()
+{
+ std::string sldr = mFramesSlider->getCurSlider();
+ if (sldr.empty())
+ {
+ return;
+ }
+ mFramesSlider->deleteCurSlider();
+ keymap_t::iterator iter = mSliderKeyMap.find(sldr);
+ if (iter != mSliderKeyMap.end())
+ {
+ LL_DEBUGS("ENVDAYEDIT") << "Removing frame from " << iter->second.mFrame << LL_ENDL;
+ LLSettingsBase::Seconds seconds(iter->second.mFrame);
+ mEditDay->removeTrackKeyframe(mCurrentTrack, seconds);
+ mSliderKeyMap.erase(iter);
+ }
+
+ mLastFrameSlider = mFramesSlider->getCurSlider();
+ mTimeSlider->setCurSliderValue(mFramesSlider->getCurSliderValue());
+ updateTabs();
+}
+
+void LLFloaterEditExtDayCycle::removeSliderFrame(F32 frame)
+{
+ keymap_t::iterator it = std::find_if(mSliderKeyMap.begin(), mSliderKeyMap.end(),
+ [frame](const keymap_t::value_type &value) { return fabs(value.second.mFrame - frame) < LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR; });
+
+ if (it != mSliderKeyMap.end())
+ {
+ mFramesSlider->deleteSlider((*it).first);
+ mSliderKeyMap.erase(it);
+ }
+
+}
+
+//-------------------------------------------------------------------------
+
+LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSignal(LLFloaterEditExtDayCycle::edit_commit_signal_t::slot_type cb)
+{
+ return mCommitSignal.connect(cb);
+}
+
+void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
+{
+ if (!mEditDay)
+ return;
+ S32 skytrack = (mCurrentTrack) ? mCurrentTrack : 1;
+ mSkyBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchSky, mEditDay, skytrack);
+ mWaterBlender = std::make_shared<LLTrackBlenderLoopingManual>(mScratchWater, mEditDay, LLSettingsDay::TRACK_WATER);
+
+ if (LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ {
+ selectTrack(LLSettingsDay::TRACK_MAX, true);
+ }
+ else
+ {
+ selectTrack(1, true);
+ }
+
+ reblendSettings();
+
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::synchronizeTabs()
+{
+ // This should probably get moved into "updateTabs"
+ std::string curslider = mFramesSlider->getCurSlider();
+ bool canedit(false);
+
+ LLSettingsWater::ptr_t psettingW;
+ LLTabContainer * tabs = mWaterTabLayoutContainer->getChild<LLTabContainer>(TABS_WATER);
+ if (mCurrentTrack == LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingW = std::static_pointer_cast<LLSettingsWater>(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingW;
+ if (!psettingW)
+ {
+ canedit = false;
+ psettingW = mScratchWater;
+ }
+
+ getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingW = mScratchWater;
+ }
+ mEditWater = psettingW;
+
+ setTabsData(tabs, psettingW, canedit);
+
+ LLSettingsSky::ptr_t psettingS;
+ canedit = false;
+ tabs = mSkyTabLayoutContainer->getChild<LLTabContainer>(TABS_SKYS);
+ if (mCurrentTrack != LLSettingsDay::TRACK_WATER)
+ {
+ if (!mEditDay)
+ {
+ canedit = false;
+ }
+ else if (!curslider.empty())
+ {
+ canedit = !mIsPlaying;
+ // either search mEditDay or retrieve from mSliderKeyMap
+ keymap_t::iterator slider_it = mSliderKeyMap.find(curslider);
+ if (slider_it != mSliderKeyMap.end())
+ {
+ psettingS = std::static_pointer_cast<LLSettingsSky>(slider_it->second.pSettings);
+ }
+ }
+ mCurrentEdit = psettingS;
+ if (!psettingS)
+ {
+ canedit = false;
+ psettingS = mScratchSky;
+ }
+
+ getChild<LLUICtrl>(ICN_LOCK_EDIT)->setVisible(!canedit);
+ }
+ else
+ {
+ psettingS = mScratchSky;
+ }
+ mEditSky = psettingS;
+
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ setTabsData(tabs, psettingS, canedit);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, mEditSky, mEditWater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterEditExtDayCycle::setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable)
+{
+ S32 count = tabcontainer->getTabCount();
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tabcontainer->getPanelByIndex(idx));
+ if (panel)
+ {
+ panel->setCanChangeSettings(editable & mCanMod);
+ panel->setSettings(settings);
+ }
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::reblendSettings()
+{
+ F64 position = mTimeSlider->getCurSliderValue();
+
+ if ((mSkyBlender->getTrack() != mCurrentTrack) && (mCurrentTrack != LLSettingsDay::TRACK_WATER))
+ {
+ mSkyBlender->switchTrack(mCurrentTrack, position);
+ }
+ else
+ mSkyBlender->setPosition(position);
+
+ mWaterBlender->setPosition(position);
+}
+
+void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
+{
+ if (!mCommitSignal.empty())
+ {
+ mCommitSignal(day);
+
+ closeFloater();
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isRemovingFrameAllowed()
+{
+ if (mFramesSlider->getCurSlider().empty()) return false;
+
+ if (mCurrentTrack <= LLSettingsDay::TRACK_GROUND_LEVEL)
+ {
+ return (mSliderKeyMap.size() > 1);
+ }
+ else
+ {
+ return (mSliderKeyMap.size() > 0);
+ }
+}
+
+bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
+{
+ if (!mFramesSlider->getCurSlider().empty() || !mEditDay) return false;
+
+ LLSettingsBase::Seconds frame(mTimeSlider->getCurSliderValue());
+ if ((mEditDay->getSettingsNearKeyframe(frame, mCurrentTrack, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR)).second)
+ {
+ return false;
+ }
+ return mFramesSlider->canAddSliders();
+}
+
+void LLFloaterEditExtDayCycle::doImportFromDisk()
+{ // Load a a legacy Windlight XML from disk.
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
+
+void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
+{
+ LLSD messages;
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_DEBUGS("ENVDAYEDIT") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsDay::ptr_t legacyday = LLEnvironment::createDayCycleFromLegacyPreset(filename, messages);
+
+ if (!legacyday)
+ {
+ LLNotificationsUtil::add("WLImportFail", messages);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ mCurrentTrack = 1;
+ setDirtyFlag();
+ setEditDayCycle(legacyday);
+}
+
+void LLFloaterEditExtDayCycle::startPlay()
+{
+ doCloseInventoryFloater();
+ doCloseTrackFloater();
+
+ mIsPlaying = true;
+ mFramesSlider->resetCurSlider();
+ mPlayTimer.reset();
+ mPlayTimer.start();
+ gIdleCallbacks.addFunction(onIdlePlay, this);
+ mPlayStartFrame = mTimeSlider->getCurSliderValue();
+
+ getChild<LLView>("play_layout", true)->setVisible(FALSE);
+ getChild<LLView>("pause_layout", true)->setVisible(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::stopPlay()
+{
+ if (!mIsPlaying)
+ return;
+
+ mIsPlaying = false;
+ gIdleCallbacks.deleteFunction(onIdlePlay, this);
+ mPlayTimer.stop();
+ F32 frame = mTimeSlider->getCurSliderValue();
+ selectFrame(frame, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+
+ getChild<LLView>("play_layout", true)->setVisible(TRUE);
+ getChild<LLView>("pause_layout", true)->setVisible(FALSE);
+}
+
+//static
+void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data)
+{
+ if (!gDisconnected)
+ {
+ LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data;
+
+ F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS;
+ F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f);
+
+ self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding
+ self->mSkyBlender->setPosition(new_frame);
+ self->mWaterBlender->setPosition(new_frame);
+ self->synchronizeTabs();
+ self->updateTimeAndLabel();
+ self->updateButtons();
+ }
+}
+
+
+void LLFloaterEditExtDayCycle::clearDirtyFlag()
+{
+ mIsDirty = false;
+
+ LLTabContainer* tab_container = mSkyTabLayoutContainer->getChild<LLTabContainer>("sky_tabs");
+ S32 tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+ tab_container = mWaterTabLayoutContainer->getChild<LLTabContainer>("water_tabs");
+ tab_count = tab_container->getTabCount();
+
+ for (S32 idx = 0; idx < tab_count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(tab_container->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+}
+
+void LLFloaterEditExtDayCycle::doOpenTrackFloater(const LLSD &args)
+{
+ LLFloaterTrackPicker *picker = static_cast<LLFloaterTrackPicker *>(mTrackFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterTrackPicker(this);
+
+ mTrackFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitTrackId(data.asInteger()); });
+ }
+
+ picker->showPicker(args);
+}
+
+void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
+{
+ LLFloater* floaterp = mTrackFloater.get();
+
+ if (floaterp)
+ {
+ floaterp->closeFloater(quitting);
+ }
+}
+
+LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()
+{
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null);
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
+ }
+ return picker;
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+{
+ cloneTrack(track_id, mCurrentTrack);
+}
+
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+ picker->setSettingsFilter(type);
+ picker->setSettingsItemId(curritem);
+ if (type == LLSettingsType::ST_DAYCYCLE)
+ {
+ picker->setTrackMode((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLFloaterSettingsPicker::TRACK_WATER : LLFloaterSettingsPicker::TRACK_SKY);
+ }
+ else
+ {
+ picker->setTrackMode(LLFloaterSettingsPicker::TRACK_NONE);
+ }
+ picker->openFloater();
+ picker->setFocus(TRUE);
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
+{
+ LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
+ LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLSettingsVOBase::getSettingsAsset(itemp->getAssetUUID(),
+ [this, track, frame, item_id](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoadedForInsertion(item_id, asset_id, settings, status, track, mCurrentTrack, frame); });
+ }
+}
+
+void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
+{
+ std::function<void()> cb = [this, settings, frame, source_track, dest_track]()
+ {
+ if (settings->getSettingsType() == "daycycle")
+ {
+ // Load full track
+ LLSettingsDay::ptr_t pday = std::dynamic_pointer_cast<LLSettingsDay>(settings);
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ cloneTrack(pday, LLSettingsDay::TRACK_WATER, LLSettingsDay::TRACK_WATER);
+ }
+ else
+ {
+ cloneTrack(pday, source_track, dest_track);
+ }
+ }
+ else
+ {
+ if (!mFramesSlider->canAddSliders())
+ {
+ LL_WARNS("ENVDAYEDIT") << "Attempt to add new frame when slider is full." << LL_ENDL;
+ return;
+ }
+
+ // load or replace single frame
+ LLSettingsDay::CycleTrack_t::value_type nearest = mEditDay->getSettingsNearKeyframe(frame, dest_track, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
+ if (nearest.first != LLSettingsDay::INVALID_TRACKPOS)
+ { // There is already a frame near the target location. Remove it so we can put the new one in its place.
+ mEditDay->removeTrackKeyframe(dest_track, nearest.first);
+ removeSliderFrame(nearest.first);
+ }
+
+ // Don't forget to clone (we might reuse/load it couple times)
+ if (settings->getSettingsType() == "sky")
+ {
+ // Load sky to frame
+ if (dest_track != LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load day settings as sky" << LL_ENDL;
+ }
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ // Load water to frame
+ if (dest_track == LLSettingsDay::TRACK_WATER)
+ {
+ mEditDay->setSettingsAtKeyframe(settings->buildDerivedClone(), frame, dest_track);
+ addSliderFrame(frame, settings, false);
+ }
+ else
+ {
+ LL_WARNS("ENVDAYEDIT") << "Trying to load water settings as sky" << LL_ENDL;
+ }
+ }
+ }
+ reblendSettings();
+ synchronizeTabs();
+ };
+
+ if (!settings || status)
+ {
+ LL_WARNS("ENVDAYEDIT") << "Could not load asset " << asset_id << " into frame. status=" << status << LL_ENDL;
+ return;
+ }
+
+ if (!mEditDay)
+ {
+ // day got reset while we were waiting for response
+ return;
+ }
+
+ LLInventoryItem *inv_item = gInventory.getItem(item_id);
+
+ if (inv_item
+ && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
+ || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))
+ {
+ // Need to check if item is already no-transfer, otherwise make it no-transfer
+ bool no_transfer = false;
+ if (mInventoryItem)
+ {
+ no_transfer = !mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ }
+ else
+ {
+ no_transfer = mEditDay->getFlag(LLSettingsBase::FLAG_NOTRANS);
+ }
+
+ if (!no_transfer)
+ {
+ LLSD args;
+
+ // create and show confirmation textbox
+ LLNotificationsUtil::add("SettingsMakeNoTrans", args, LLSD(),
+ [this, cb](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ mCanTrans = false;
+ mEditDay->setFlag(LLSettingsBase::FLAG_NOTRANS);
+ cb();
+ }
+ });
+ return;
+ }
+ }
+
+ cb();
+}
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
new file mode 100644
index 0000000000..9a30fb199f
--- /dev/null
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -0,0 +1,244 @@
+/**
+ * @file llfloatereditextdaycycle.h
+ * @brief Floater to create or edit a day cycle
+ *
+ * $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$
+ */
+
+#ifndef LL_LLFLOATEREDITEXTDAYCYCLE_H
+#define LL_LLFLOATEREDITEXTDAYCYCLE_H
+
+#include "llfloater.h"
+#include "llsettingsdaycycle.h"
+#include <boost/signals2.hpp>
+
+#include "llenvironment.h"
+#include "llfloatereditenvironmentbase.h"
+
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLFlyoutComboBtnCtrl;
+class LLLineEditor;
+class LLMultiSliderCtrl;
+class LLTextBox;
+class LLTimeCtrl;
+class LLTabContainer;
+
+class LLInventoryItem;
+class LLDaySettingCopiedCallback;
+
+typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;
+
+/**
+ * Floater for creating or editing a day cycle.
+ */
+class LLFloaterEditExtDayCycle : public LLFloaterEditEnvironmentBase
+{
+ LOG_CLASS(LLFloaterEditExtDayCycle);
+
+ friend class LLDaySettingCopiedCallback;
+
+public:
+ static const std::string KEY_EDIT_CONTEXT;
+ static const std::string KEY_DAY_LENGTH;
+ static const std::string KEY_CANMOD;
+
+ static const std::string VALUE_CONTEXT_INVENTORY;
+ static const std::string VALUE_CONTEXT_PARCEL;
+ static const std::string VALUE_CONTEXT_REGION;
+
+ enum edit_context_t {
+ CONTEXT_UNKNOWN,
+ CONTEXT_INVENTORY,
+ CONTEXT_PARCEL,
+ CONTEXT_REGION
+ };
+
+ typedef boost::signals2::signal<void(LLSettingsDay::ptr_t)> edit_commit_signal_t;
+ typedef boost::signals2::connection connection_t;
+
+ LLFloaterEditExtDayCycle(const LLSD &key);
+ virtual ~LLFloaterEditExtDayCycle();
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+ //virtual void onFocusReceived() override;
+ //virtual void onFocusLost() override;
+ virtual void onVisibilityChange(BOOL new_visibility) override;
+
+ connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb);
+
+ virtual void refresh() override;
+
+ void setEditDayCycle(const LLSettingsDay::ptr_t &pday);
+ void setEditDefaultDayCycle();
+ std::string getEditName() const;
+ void setEditName(const std::string &name);
+ LLUUID getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; }
+ LLUUID getEditingInventoryId() { return mInventoryId; }
+
+ virtual LLSettingsBase::ptr_t getEditSettings() const override { return mEditDay; }
+
+
+ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override;
+
+protected:
+ virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
+
+private:
+ typedef std::function<void()> on_confirm_fn;
+ F32 getCurrentFrame() const;
+
+ // flyout response/click
+ void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
+ //virtual void onClickCloseBtn(bool app_quitting = false) override;
+ //void onButtonImport();
+ void onButtonLoadFrame();
+ void onAddFrame();
+ void onRemoveFrame();
+ void onCloneTrack();
+ void onLoadTrack();
+ void onClearTrack();
+ void onCommitName(class LLLineEditor* caller, void* user_data);
+ void onTrackSelectionCallback(const LLSD& user_data);
+ void onPlayActionCallback(const LLSD& user_data);
+ // time slider clicked
+ void onTimeSliderCallback();
+ // a frame moved or frame selection changed
+ void onFrameSliderCallback(const LLSD &);
+ void onFrameSliderDoubleClick(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
+ void onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
+
+ void cloneTrack(U32 source_index, U32 dest_index);
+ void cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index);
+ void selectTrack(U32 track_index, bool force = false);
+ void selectFrame(F32 frame, F32 slop_factor);
+ void clearTabs();
+ void updateTabs();
+ void updateWaterTabs(const LLSettingsWaterPtr_t &p_water);
+ void updateSkyTabs(const LLSettingsSkyPtr_t &p_sky);
+ void updateButtons();
+ void updateLabels();
+ void updateSlider(); //generate sliders from current track
+ void updateTimeAndLabel();
+ void addSliderFrame(F32 frame, const LLSettingsBase::ptr_t &setting, bool update_ui = true);
+ void removeCurrentSliderFrame();
+ void removeSliderFrame(F32 frame);
+
+ virtual void doImportFromDisk() override;
+ void loadSettingFromFile(const std::vector<std::string>& filenames);
+ void doApplyCommit(LLSettingsDay::ptr_t day);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+
+ void doOpenTrackFloater(const LLSD &args);
+ void doCloseTrackFloater(bool quitting = false);
+ virtual LLFloaterSettingsPicker* getSettingsPicker() override;
+ void onPickerCommitTrackId(U32 track_id);
+
+ void doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem);
+ //void doCloseInventoryFloater(bool quitting = false);
+ void onPickerCommitSetting(LLUUID item_id, S32 track);
+ void onAssetLoadedForInsertion(LLUUID item_id,
+ LLUUID asset_id,
+ LLSettingsBase::ptr_t settings,
+ S32 status,
+ S32 source_track,
+ S32 dest_track,
+ LLSettingsBase::TrackPosition dest_frame);
+
+ virtual void updateEditEnvironment() override;
+ void synchronizeTabs();
+ void reblendSettings();
+
+ void setTabsData(LLTabContainer * tabcontainer, const LLSettingsBase::ptr_t &settings, bool editable);
+
+ // play functions
+ void startPlay();
+ void stopPlay();
+ static void onIdlePlay(void *);
+
+ bool getIsDirty() const { return mIsDirty; }
+ void setDirtyFlag() { mIsDirty = true; }
+ virtual void clearDirtyFlag() override;
+
+ bool isRemovingFrameAllowed();
+ bool isAddingFrameAllowed();
+
+ LLSettingsDay::ptr_t mEditDay; // edited copy
+ LLSettingsDay::Seconds mDayLength;
+ U32 mCurrentTrack;
+ std::string mLastFrameSlider;
+ bool mShiftCopyEnabled;
+
+ LLUUID mExpectingAssetId;
+
+ LLButton* mAddFrameButton;
+ LLButton* mDeleteFrameButton;
+ LLButton* mImportButton;
+ LLButton* mLoadFrame;
+ LLButton * mCloneTrack;
+ LLButton * mLoadTrack;
+ LLButton * mClearTrack;
+ LLMultiSliderCtrl* mTimeSlider;
+ LLMultiSliderCtrl* mFramesSlider;
+ LLView* mSkyTabLayoutContainer;
+ LLView* mWaterTabLayoutContainer;
+ LLTextBox* mCurrentTimeLabel;
+ LLFlyoutComboBtnCtrl * mFlyoutControl;
+
+ LLHandle<LLFloater> mTrackFloater;
+
+ LLTrackBlenderLoopingManual::ptr_t mSkyBlender;
+ LLTrackBlenderLoopingManual::ptr_t mWaterBlender;
+ LLSettingsSky::ptr_t mScratchSky;
+ LLSettingsWater::ptr_t mScratchWater;
+ LLSettingsBase::ptr_t mCurrentEdit;
+ LLSettingsSky::ptr_t mEditSky;
+ LLSettingsWater::ptr_t mEditWater;
+
+ LLFrameTimer mPlayTimer;
+ F32 mPlayStartFrame; // an env frame
+ bool mIsPlaying;
+
+ edit_commit_signal_t mCommitSignal;
+
+ edit_context_t mEditContext;
+
+ // For map of sliders to parameters
+ class FrameData
+ {
+ public:
+ FrameData() : mFrame(0) {};
+ FrameData(F32 frame, LLSettingsBase::ptr_t settings) : mFrame(frame), pSettings(settings) {};
+ F32 mFrame;
+ LLSettingsBase::ptr_t pSettings;
+ };
+ typedef std::map<std::string, FrameData> keymap_t;
+ keymap_t mSliderKeyMap; //slider's keys vs old_frames&settings, shadows mFramesSlider
+};
+
+#endif // LL_LLFloaterEditExtDayCycle_H
diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp
index d809211ea7..6bdc5ee823 100644
--- a/indra/newview/llfloatereditsky.cpp
+++ b/indra/newview/llfloatereditsky.cpp
@@ -28,6 +28,8 @@
#include "llfloatereditsky.h"
+#include <boost/make_shared.hpp>
+
// libs
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -38,6 +40,7 @@
#include "llsliderctrl.h"
#include "lltabcontainer.h"
#include "lltimectrl.h"
+#include "lljoystickbutton.h"
// newview
#include "llagent.h"
@@ -45,15 +48,18 @@
#include "llregioninfomodel.h"
#include "llviewerregion.h"
-static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f;
-static const F32 WL_BLUE_HORIZON_DENSITY_SCALE = 2.0f;
-static const F32 WL_CLOUD_SLIDER_SCALE = 1.0f;
+#include "v3colorutil.h"
+#include "llenvironment.h"
+#include "llenvadapters.h"
-static F32 sun_pos_to_time24(F32 sun_pos)
+namespace
{
- return fmodf(sun_pos * 24.0f + 6, 24.0f);
+ const F32 WL_SUN_AMBIENT_SLIDER_SCALE(3.0f);
+ const F32 WL_BLUE_HORIZON_DENSITY_SCALE(2.0f);
+ const F32 WL_CLOUD_SLIDER_SCALE(1.0f);
}
+
static F32 time24_to_sun_pos(F32 time24)
{
F32 sun_pos = fmodf((time24 - 6) / 24.0f, 1.0f);
@@ -61,12 +67,13 @@ static F32 time24_to_sun_pos(F32 time24)
return sun_pos;
}
-LLFloaterEditSky::LLFloaterEditSky(const LLSD &key)
-: LLFloater(key)
-, mSkyPresetNameEditor(NULL)
-, mSkyPresetCombo(NULL)
-, mMakeDefaultCheckBox(NULL)
-, mSaveButton(NULL)
+LLFloaterEditSky::LLFloaterEditSky(const LLSD &key):
+ LLFloater(key),
+ mSkyPresetNameEditor(NULL),
+ mSkyPresetCombo(NULL),
+ mMakeDefaultCheckBox(NULL),
+ mSaveButton(NULL),
+ mSkyAdapter()
{
}
@@ -77,11 +84,14 @@ BOOL LLFloaterEditSky::postBuild()
mSkyPresetCombo = getChild<LLComboBox>("sky_preset_combo");
mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
mSaveButton = getChild<LLButton>("save");
+ mSkyAdapter = boost::make_shared<LLSkySettingsAdapter>();
+
+ LLEnvironment::instance().setSkyListChange(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this));
initCallbacks();
- // Create the sun position scrubber on the slider.
- getChild<LLMultiSliderCtrl>("WLSunPos")->addSlider(12.f);
+// // Create the sun position scrubber on the slider.
+// getChild<LLMultiSliderCtrl>("WLSunPos")->addSlider(12.f);
return TRUE;
}
@@ -115,7 +125,8 @@ void LLFloaterEditSky::onClose(bool app_quitting)
{
if (!app_quitting) // there's no point to change environment if we're quitting
{
- LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
}
}
@@ -137,71 +148,47 @@ void LLFloaterEditSky::initCallbacks(void)
mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnSave, this));
getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditSky::onBtnCancel, this));
- LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditSky::onRegionSettingsChange, this));
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditSky::onSkyPresetListChange, this));
-
// Connect to region info updates.
LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditSky::onRegionInfoUpdate, this));
- //-------------------------------------------------------------------------
-
- LLWLParamManager& param_mgr = LLWLParamManager::instance();
-
- // blue horizon
- getChild<LLUICtrl>("WLBlueHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mBlueHorizon));
-
- // haze density, horizon, mult, and altitude
- getChild<LLUICtrl>("WLHazeDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mHazeDensity));
- getChild<LLUICtrl>("WLHazeHorizon")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mHazeHorizon));
- getChild<LLUICtrl>("WLDensityMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mDensityMult));
- getChild<LLUICtrl>("WLMaxAltitude")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mMaxAlt));
-
- // blue density
- getChild<LLUICtrl>("WLBlueDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mBlueDensity));
-
- // Lighting
-
// sunlight
- getChild<LLUICtrl>("WLSunlight")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mSunlight));
+ getChild<LLUICtrl>("WLSunlight")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &mSkyAdapter->mSunlight));
// glow
- getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, &param_mgr.mGlow));
- getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, &param_mgr.mGlow));
-
- // ambient
- getChild<LLUICtrl>("WLAmbient")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mAmbient));
+ getChild<LLUICtrl>("WLGlowR")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowRMoved, this, _1, &mSkyAdapter->mGlow));
+ getChild<LLUICtrl>("WLGlowB")->setCommitCallback(boost::bind(&LLFloaterEditSky::onGlowBMoved, this, _1, &mSkyAdapter->mGlow));
// time of day
- getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &param_mgr.mLightnorm)); // multi-slider
- getChild<LLTimeCtrl>("WLDayTime")->setCommitCallback(boost::bind(&LLFloaterEditSky::onTimeChanged, this)); // time ctrl
- getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &param_mgr.mLightnorm));
+// getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &mSkyAdapter->mLightnorm)); // multi-slider
+// getChild<LLTimeCtrl>("WLDayTime")->setCommitCallback(boost::bind(&LLFloaterEditSky::onTimeChanged, this)); // time ctrl
+// getChild<LLUICtrl>("WLEastAngle")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunMoved, this, _1, &mSkyAdapter->mLightnorm));
+ getChild<LLJoystickQuaternion>("WLSunRotation")->setCommitCallback(boost::bind(&LLFloaterEditSky::onSunRotationChanged, this));
+ getChild<LLJoystickQuaternion>("WLMoonRotation")->setCommitCallback(boost::bind(&LLFloaterEditSky::onMoonRotationChanged, this));
// Clouds
// Cloud Color
- getChild<LLUICtrl>("WLCloudColor")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &param_mgr.mCloudColor));
+ getChild<LLUICtrl>("WLCloudColor")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlMoved, this, _1, &mSkyAdapter->mCloudColor));
// Cloud
- getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mCloudMain));
- getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &param_mgr.mCloudMain));
- getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &param_mgr.mCloudMain));
+ getChild<LLUICtrl>("WLCloudX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &mSkyAdapter->mCloudMain));
+ getChild<LLUICtrl>("WLCloudY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &mSkyAdapter->mCloudMain));
+ getChild<LLUICtrl>("WLCloudDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &mSkyAdapter->mCloudMain));
// Cloud Detail
- getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &param_mgr.mCloudDetail));
- getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &param_mgr.mCloudDetail));
- getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &param_mgr.mCloudDetail));
+ getChild<LLUICtrl>("WLCloudDetailX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlRMoved, this, _1, &mSkyAdapter->mCloudDetail));
+ getChild<LLUICtrl>("WLCloudDetailY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlGMoved, this, _1, &mSkyAdapter->mCloudDetail));
+ getChild<LLUICtrl>("WLCloudDetailDensity")->setCommitCallback(boost::bind(&LLFloaterEditSky::onColorControlBMoved, this, _1, &mSkyAdapter->mCloudDetail));
// Cloud extras
- getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mCloudCoverage));
- getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mCloudScale));
- getChild<LLUICtrl>("WLCloudLockX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXToggled, this, _1));
- getChild<LLUICtrl>("WLCloudLockY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYToggled, this, _1));
+ getChild<LLUICtrl>("WLCloudCoverage")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mCloudCoverage));
+ getChild<LLUICtrl>("WLCloudScale")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mCloudScale));
getChild<LLUICtrl>("WLCloudScrollX")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollXMoved, this, _1));
getChild<LLUICtrl>("WLCloudScrollY")->setCommitCallback(boost::bind(&LLFloaterEditSky::onCloudScrollYMoved, this, _1));
- getChild<LLUICtrl>("WLDistanceMult")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mDistanceMult));
+
// Dome
- getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &param_mgr.mWLGamma));
+ getChild<LLUICtrl>("WLGamma")->setCommitCallback(boost::bind(&LLFloaterEditSky::onFloatControlMoved, this, _1, &mSkyAdapter->mWLGamma));
getChild<LLUICtrl>("WLStarAlpha")->setCommitCallback(boost::bind(&LLFloaterEditSky::onStarAlphaMoved, this, _1));
}
@@ -209,320 +196,229 @@ void LLFloaterEditSky::initCallbacks(void)
void LLFloaterEditSky::syncControls()
{
- bool err;
-
- LLWLParamManager * param_mgr = LLWLParamManager::getInstance();
-
- LLWLParamSet& cur_params = param_mgr->mCurParams;
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ mEditSettings = psky;
- // blue horizon
- param_mgr->mBlueHorizon = cur_params.getVector(param_mgr->mBlueHorizon.mName, err);
- setColorSwatch("WLBlueHorizon", param_mgr->mBlueHorizon, WL_BLUE_HORIZON_DENSITY_SCALE);
+ std::string name = psky->getName();
- // haze density, horizon, mult, and altitude
- param_mgr->mHazeDensity = cur_params.getFloat(param_mgr->mHazeDensity.mName, err);
- childSetValue("WLHazeDensity", (F32) param_mgr->mHazeDensity);
- param_mgr->mHazeHorizon = cur_params.getFloat(param_mgr->mHazeHorizon.mName, err);
- childSetValue("WLHazeHorizon", (F32) param_mgr->mHazeHorizon);
- param_mgr->mDensityMult = cur_params.getFloat(param_mgr->mDensityMult.mName, err);
- childSetValue("WLDensityMult", ((F32) param_mgr->mDensityMult) * param_mgr->mDensityMult.mult);
- param_mgr->mMaxAlt = cur_params.getFloat(param_mgr->mMaxAlt.mName, err);
- childSetValue("WLMaxAltitude", (F32) param_mgr->mMaxAlt);
-
- // blue density
- param_mgr->mBlueDensity = cur_params.getVector(param_mgr->mBlueDensity.mName, err);
- setColorSwatch("WLBlueDensity", param_mgr->mBlueDensity, WL_BLUE_HORIZON_DENSITY_SCALE);
+ mSkyPresetNameEditor->setText(name);
+ mSkyPresetCombo->setValue(name);
// Lighting
// sunlight
- param_mgr->mSunlight = cur_params.getVector(param_mgr->mSunlight.mName, err);
- setColorSwatch("WLSunlight", param_mgr->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE);
+ mSkyAdapter->mSunlight.setColor3( psky->getSunlightColor() );
+ setColorSwatch("WLSunlight", mSkyAdapter->mSunlight, WL_SUN_AMBIENT_SLIDER_SCALE);
// glow
- param_mgr->mGlow = cur_params.getVector(param_mgr->mGlow.mName, err);
- childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f);
- childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f);
-
- // ambient
- param_mgr->mAmbient = cur_params.getVector(param_mgr->mAmbient.mName, err);
- setColorSwatch("WLAmbient", param_mgr->mAmbient, WL_SUN_AMBIENT_SLIDER_SCALE);
-
- F32 time24 = sun_pos_to_time24(param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI);
- getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE);
- getChild<LLTimeCtrl>("WLDayTime")->setTime24(time24);
- childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI);
+ mSkyAdapter->mGlow.setColor3( psky->getGlow() );
+ childSetValue("WLGlowR", 2 - mSkyAdapter->mGlow.getRed() / 20.0f);
+ childSetValue("WLGlowB", -mSkyAdapter->mGlow.getBlue() / 5.0f);
+
+// LLSettingsSky::azimalt_t azal = psky->getSunRotationAzAl();
+//
+// F32 time24 = sun_pos_to_time24(azal.second / F_TWO_PI);
+// getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE);
+// getChild<LLTimeCtrl>("WLDayTime")->setTime24(time24);
+// childSetValue("WLEastAngle", azal.first / F_TWO_PI);
+ getChild<LLJoystickQuaternion>("WLSunRotation")->setRotation(psky->getSunRotation());
+ getChild<LLJoystickQuaternion>("WLMoonRotation")->setRotation(psky->getMoonRotation());
// Clouds
// Cloud Color
- param_mgr->mCloudColor = cur_params.getVector(param_mgr->mCloudColor.mName, err);
- setColorSwatch("WLCloudColor", param_mgr->mCloudColor, WL_CLOUD_SLIDER_SCALE);
+ mSkyAdapter->mCloudColor.setColor3( psky->getCloudColor() );
+ setColorSwatch("WLCloudColor", mSkyAdapter->mCloudColor, WL_CLOUD_SLIDER_SCALE);
// Cloud
- param_mgr->mCloudMain = cur_params.getVector(param_mgr->mCloudMain.mName, err);
- childSetValue("WLCloudX", param_mgr->mCloudMain.r);
- childSetValue("WLCloudY", param_mgr->mCloudMain.g);
- childSetValue("WLCloudDensity", param_mgr->mCloudMain.b);
+ mSkyAdapter->mCloudMain.setColor3( psky->getCloudPosDensity1() );
+ childSetValue("WLCloudX", mSkyAdapter->mCloudMain.getRed());
+ childSetValue("WLCloudY", mSkyAdapter->mCloudMain.getGreen());
+ childSetValue("WLCloudDensity", mSkyAdapter->mCloudMain.getBlue());
// Cloud Detail
- param_mgr->mCloudDetail = cur_params.getVector(param_mgr->mCloudDetail.mName, err);
- childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r);
- childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g);
- childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b);
+ mSkyAdapter->mCloudDetail.setColor3( psky->getCloudPosDensity2() );
+ childSetValue("WLCloudDetailX", mSkyAdapter->mCloudDetail.getRed());
+ childSetValue("WLCloudDetailY", mSkyAdapter->mCloudDetail.getGreen());
+ childSetValue("WLCloudDetailDensity", mSkyAdapter->mCloudDetail.getBlue());
// Cloud extras
- param_mgr->mCloudCoverage = cur_params.getFloat(param_mgr->mCloudCoverage.mName, err);
- param_mgr->mCloudScale = cur_params.getFloat(param_mgr->mCloudScale.mName, err);
- childSetValue("WLCloudCoverage", (F32) param_mgr->mCloudCoverage);
- childSetValue("WLCloudScale", (F32) param_mgr->mCloudScale);
+ mSkyAdapter->mCloudCoverage = psky->getCloudShadow();
+ mSkyAdapter->mCloudScale = psky->getCloudScale();
+ childSetValue("WLCloudCoverage", (F32) mSkyAdapter->mCloudCoverage);
+ childSetValue("WLCloudScale", (F32) mSkyAdapter->mCloudScale);
// cloud scrolling
- bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX();
- bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY();
- childSetValue("WLCloudLockX", lockX);
- childSetValue("WLCloudLockY", lockY);
+ LLVector2 scroll_rate = psky->getCloudScrollRate();
+
+ // LAPRAS: These should go away...
+ childDisable("WLCloudLockX");
+ childDisable("WLCloudLockY");
// disable if locked, enable if not
- if (lockX)
- {
- childDisable("WLCloudScrollX");
- }
- else
- {
- childEnable("WLCloudScrollX");
- }
- if (lockY)
- {
- childDisable("WLCloudScrollY");
- }
- else
- {
- childEnable("WLCloudScrollY");
- }
+ childEnable("WLCloudScrollX");
+ childEnable("WLCloudScrollY");
// *HACK cloud scrolling is off my an additive of 10
- childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f);
- childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f);
-
- param_mgr->mDistanceMult = cur_params.getFloat(param_mgr->mDistanceMult.mName, err);
- childSetValue("WLDistanceMult", (F32) param_mgr->mDistanceMult);
+ childSetValue("WLCloudScrollX", scroll_rate[0] - 10.0f);
+ childSetValue("WLCloudScrollY", scroll_rate[1] - 10.0f);
// Tweak extras
- param_mgr->mWLGamma = cur_params.getFloat(param_mgr->mWLGamma.mName, err);
- childSetValue("WLGamma", (F32) param_mgr->mWLGamma);
+ mSkyAdapter->mWLGamma = psky->getGamma();
+ childSetValue("WLGamma", (F32) mSkyAdapter->mWLGamma);
- childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness());
+ childSetValue("WLStarAlpha", psky->getStarBrightness());
}
void LLFloaterEditSky::setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k)
{
// Set the value, dividing it by <k> first.
- LLVector4 color_vec = from_ctrl;
- getChild<LLColorSwatchCtrl>(name)->set(LLColor4(color_vec / k));
+ LLColor4 color = from_ctrl.getColor4();
+ getChild<LLColorSwatchCtrl>(name)->set(color / k);
}
// color control callbacks
void LLFloaterEditSky::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
- LLVector4 color_vec(swatch->get().mV);
-
- // Set intensity to maximum of the RGB values.
- color_vec.mV[3] = llmax(color_vec.mV[0], llmax(color_vec.mV[1], color_vec.mV[2]));
+ LLColor4 color_vec(swatch->get().mV);
// Multiply RGB values by the appropriate factor.
F32 k = WL_CLOUD_SLIDER_SCALE;
- if (color_ctrl->isSunOrAmbientColor)
+ if (color_ctrl->getIsSunOrAmbientColor())
{
k = WL_SUN_AMBIENT_SLIDER_SCALE;
}
- if (color_ctrl->isBlueHorizonOrDensity)
+ else if (color_ctrl->getIsBlueHorizonOrDensity())
{
k = WL_BLUE_HORIZON_DENSITY_SCALE;
}
color_vec *= k; // intensity isn't affected by the multiplication
+ // Set intensity to maximum of the RGB values.
+ color_vec.mV[3] = color_max(color_vec);
+
// Apply the new RGBI value.
- *color_ctrl = color_vec;
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
- LLWLParamManager::getInstance()->propagateParameters();
+ color_ctrl->setColor4(color_vec);
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditSky::onColorControlRMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
- color_ctrl->r = sldr_ctrl->getValueF32();
- if (color_ctrl->isSunOrAmbientColor)
- {
- color_ctrl->r *= WL_SUN_AMBIENT_SLIDER_SCALE;
- }
- if (color_ctrl->isBlueHorizonOrDensity)
+ F32 red_value = sldr_ctrl->getValueF32();
+ F32 k = 1.0f;
+
+ if (color_ctrl->getIsSunOrAmbientColor())
{
- color_ctrl->r *= WL_BLUE_HORIZON_DENSITY_SCALE;
+ k = WL_SUN_AMBIENT_SLIDER_SCALE;
}
-
- // move i if it's the max
- if (color_ctrl->r >= color_ctrl->g && color_ctrl->r >= color_ctrl->b && color_ctrl->hasSliderName)
+ if (color_ctrl->getIsBlueHorizonOrDensity())
{
- color_ctrl->i = color_ctrl->r;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- if (color_ctrl->isSunOrAmbientColor)
- {
- childSetValue(name, color_ctrl->r / WL_SUN_AMBIENT_SLIDER_SCALE);
- }
- else if (color_ctrl->isBlueHorizonOrDensity)
- {
- childSetValue(name, color_ctrl->r / WL_BLUE_HORIZON_DENSITY_SCALE);
- }
- else
- {
- childSetValue(name, color_ctrl->r);
- }
+ k = WL_BLUE_HORIZON_DENSITY_SCALE;
}
+ color_ctrl->setRed(red_value * k);
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
-
- LLWLParamManager::getInstance()->propagateParameters();
+ adjustIntensity(color_ctrl, red_value, k);
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditSky::onColorControlGMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
+ F32 green_value = sldr_ctrl->getValueF32();
+ F32 k = 1.0f;
- color_ctrl->g = sldr_ctrl->getValueF32();
- if (color_ctrl->isSunOrAmbientColor)
- {
- color_ctrl->g *= WL_SUN_AMBIENT_SLIDER_SCALE;
- }
- if (color_ctrl->isBlueHorizonOrDensity)
- {
- color_ctrl->g *= WL_BLUE_HORIZON_DENSITY_SCALE;
- }
+ if (color_ctrl->getIsSunOrAmbientColor())
+ {
+ k = WL_SUN_AMBIENT_SLIDER_SCALE;
+ }
+ if (color_ctrl->getIsBlueHorizonOrDensity())
+ {
+ k = WL_BLUE_HORIZON_DENSITY_SCALE;
+ }
+ color_ctrl->setGreen(green_value * k);
- // move i if it's the max
- if (color_ctrl->g >= color_ctrl->r && color_ctrl->g >= color_ctrl->b && color_ctrl->hasSliderName)
- {
- color_ctrl->i = color_ctrl->g;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- if (color_ctrl->isSunOrAmbientColor)
- {
- childSetValue(name, color_ctrl->g / WL_SUN_AMBIENT_SLIDER_SCALE);
- }
- else if (color_ctrl->isBlueHorizonOrDensity)
- {
- childSetValue(name, color_ctrl->g / WL_BLUE_HORIZON_DENSITY_SCALE);
- }
- else
- {
- childSetValue(name, color_ctrl->g);
- }
- }
-
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
-
- LLWLParamManager::getInstance()->propagateParameters();
+ adjustIntensity(color_ctrl, green_value, k);
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditSky::onColorControlBMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
+ F32 blue_value = sldr_ctrl->getValueF32();
+ F32 k = 1.0f;
- color_ctrl->b = sldr_ctrl->getValueF32();
- if (color_ctrl->isSunOrAmbientColor)
- {
- color_ctrl->b *= WL_SUN_AMBIENT_SLIDER_SCALE;
- }
- if (color_ctrl->isBlueHorizonOrDensity)
- {
- color_ctrl->b *= WL_BLUE_HORIZON_DENSITY_SCALE;
- }
+ if (color_ctrl->getIsSunOrAmbientColor())
+ {
+ k = WL_SUN_AMBIENT_SLIDER_SCALE;
+ }
+ if (color_ctrl->getIsBlueHorizonOrDensity())
+ {
+ k = WL_BLUE_HORIZON_DENSITY_SCALE;
+ }
+ color_ctrl->setBlue(blue_value * k);
- // move i if it's the max
- if (color_ctrl->b >= color_ctrl->r && color_ctrl->b >= color_ctrl->g && color_ctrl->hasSliderName)
- {
- color_ctrl->i = color_ctrl->b;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- if (color_ctrl->isSunOrAmbientColor)
- {
- childSetValue(name, color_ctrl->b / WL_SUN_AMBIENT_SLIDER_SCALE);
- }
- else if (color_ctrl->isBlueHorizonOrDensity)
- {
- childSetValue(name, color_ctrl->b / WL_BLUE_HORIZON_DENSITY_SCALE);
- }
- else
- {
- childSetValue(name, color_ctrl->b);
- }
- }
+ adjustIntensity(color_ctrl, blue_value, k);
+ color_ctrl->update(mEditSettings);
+}
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
+void LLFloaterEditSky::adjustIntensity(WLColorControl *ctrl, F32 val, F32 scale)
+{
+ if (ctrl->getHasSliderName())
+ {
+ LLColor4 color = ctrl->getColor4();
+ F32 i = color_max(color) / scale;
+ ctrl->setIntensity(i);
+ std::string name = ctrl->getSliderName();
+ name.append("I");
- LLWLParamManager::getInstance()->propagateParameters();
+ childSetValue(name, i);
+ }
}
+
/// GLOW SPECIFIC CODE
void LLFloaterEditSky::onGlowRMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
// scaled by 20
- color_ctrl->r = (2 - sldr_ctrl->getValueF32()) * 20;
+ color_ctrl->setRed((2 - sldr_ctrl->getValueF32()) * 20);
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
- LLWLParamManager::getInstance()->propagateParameters();
+ color_ctrl->update(mEditSettings);
}
/// \NOTE that we want NEGATIVE (-) B
void LLFloaterEditSky::onGlowBMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
WLColorControl* color_ctrl = static_cast<WLColorControl *>(userdata);
/// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big
- color_ctrl->b = -sldr_ctrl->getValueF32() * 5;
+ color_ctrl->setBlue(-sldr_ctrl->getValueF32() * 5);
- color_ctrl->update(LLWLParamManager::getInstance()->mCurParams);
- LLWLParamManager::getInstance()->propagateParameters();
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
WLFloatControl * floatControl = static_cast<WLFloatControl *>(userdata);
- floatControl->x = sldr_ctrl->getValueF32() / floatControl->mult;
+ floatControl->setValue(sldr_ctrl->getValueF32() / floatControl->getMult());
- floatControl->update(LLWLParamManager::getInstance()->mCurParams);
- LLWLParamManager::getInstance()->propagateParameters();
+ floatControl->update(mEditSettings);
}
@@ -531,8 +427,6 @@ void LLFloaterEditSky::onFloatControlMoved(LLUICtrl* ctrl, void* userdata)
// time of day
void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLMultiSliderCtrl* sun_msldr = getChild<LLMultiSliderCtrl>("WLSunPos");
LLSliderCtrl* east_sldr = getChild<LLSliderCtrl>("WLEastAngle");
LLTimeCtrl* time_ctrl = getChild<LLTimeCtrl>("WLDayTime");
@@ -542,99 +436,60 @@ void LLFloaterEditSky::onSunMoved(LLUICtrl* ctrl, void* userdata)
time_ctrl->setTime24(time24); // sync the time ctrl with the new sun position
// get the two angles
- LLWLParamManager * param_mgr = LLWLParamManager::getInstance();
-
- param_mgr->mCurParams.setSunAngle(F_TWO_PI * time24_to_sun_pos(time24));
- param_mgr->mCurParams.setEastAngle(F_TWO_PI * east_sldr->getValueF32());
+ F32 azimuth = F_TWO_PI * east_sldr->getValueF32();
+ F32 altitude = F_TWO_PI * time24_to_sun_pos(time24);
+ mEditSettings->setSunRotation(azimuth, altitude);
+ mEditSettings->setMoonRotation(azimuth + F_PI, -altitude);
- // set the sun vector
- color_ctrl->r = -sin(param_mgr->mCurParams.getEastAngle()) *
- cos(param_mgr->mCurParams.getSunAngle());
- color_ctrl->g = sin(param_mgr->mCurParams.getSunAngle());
- color_ctrl->b = cos(param_mgr->mCurParams.getEastAngle()) *
- cos(param_mgr->mCurParams.getSunAngle());
- color_ctrl->i = 1.f;
+ LLVector4 sunnorm( mEditSettings->getSunDirection(), 1.f );
- color_ctrl->update(param_mgr->mCurParams);
- param_mgr->propagateParameters();
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditSky::onTimeChanged()
{
F32 time24 = getChild<LLTimeCtrl>("WLDayTime")->getTime24();
getChild<LLMultiSliderCtrl>("WLSunPos")->setCurSliderValue(time24, TRUE);
- onSunMoved(getChild<LLUICtrl>("WLSunPos"), &LLWLParamManager::instance().mLightnorm);
+ onSunMoved(getChild<LLUICtrl>("WLSunPos"), &(mSkyAdapter->mLightnorm));
}
-void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl)
+void LLFloaterEditSky::onSunRotationChanged()
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ LLJoystickQuaternion* sun_spinner = getChild<LLJoystickQuaternion>("WLSunRotation");
+ LLQuaternion sunrot(sun_spinner->getRotation());
- LLWLParamManager::getInstance()->mCurParams.setStarBrightness(sldr_ctrl->getValueF32());
+ mEditSettings->setSunRotation(sunrot);
}
-// Clouds
-void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl)
+void LLFloaterEditSky::onMoonRotationChanged()
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
+ LLJoystickQuaternion* moon_spinner = getChild<LLJoystickQuaternion>("WLMoonRotation");
+ LLQuaternion moonrot(moon_spinner->getRotation());
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- // *HACK all cloud scrolling is off by an additive of 10.
- LLWLParamManager::getInstance()->mCurParams.setCloudScrollX(sldr_ctrl->getValueF32() + 10.0f);
+ mEditSettings->setMoonRotation(moonrot);
}
-void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl)
+void LLFloaterEditSky::onStarAlphaMoved(LLUICtrl* ctrl)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- // *HACK all cloud scrolling is off by an additive of 10.
- LLWLParamManager::getInstance()->mCurParams.setCloudScrollY(sldr_ctrl->getValueF32() + 10.0f);
+ mEditSettings->setStarBrightness(sldr_ctrl->getValueF32());
}
-void LLFloaterEditSky::onCloudScrollXToggled(LLUICtrl* ctrl)
+// Clouds
+void LLFloaterEditSky::onCloudScrollXMoved(LLUICtrl* ctrl)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
- LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl);
-
- bool lock = cb_ctrl->get();
- LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollX(!lock);
-
- LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollX");
-
- if (cb_ctrl->get())
- {
- sldr->setEnabled(false);
- }
- else
- {
- sldr->setEnabled(true);
- }
-
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ // *HACK all cloud scrolling is off by an additive of 10.
+ mEditSettings->setCloudScrollRateX(sldr_ctrl->getValueF32() + 10.0f);
}
-void LLFloaterEditSky::onCloudScrollYToggled(LLUICtrl* ctrl)
+void LLFloaterEditSky::onCloudScrollYMoved(LLUICtrl* ctrl)
{
- LLWLParamManager::getInstance()->mAnimator.deactivate();
-
- LLCheckBoxCtrl* cb_ctrl = static_cast<LLCheckBoxCtrl*>(ctrl);
- bool lock = cb_ctrl->get();
- LLWLParamManager::getInstance()->mCurParams.setEnableCloudScrollY(!lock);
-
- LLSliderCtrl* sldr = getChild<LLSliderCtrl>("WLCloudScrollY");
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- if (cb_ctrl->get())
- {
- sldr->setEnabled(false);
- }
- else
- {
- sldr->setEnabled(true);
- }
+ // *HACK all cloud scrolling is off by an additive of 10.
+ mEditSettings->setCloudScrollRateY(sldr_ctrl->getValueF32() + 10.0f);
}
//=================================================================================================
@@ -664,38 +519,12 @@ void LLFloaterEditSky::refreshSkyPresetsList()
{
mSkyPresetCombo->removeall();
- LLWLParamManager::preset_name_list_t region_presets, user_presets, sys_presets;
- LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
+ LLEnvironment::list_name_id_t list = LLEnvironment::instance().getSkyList();
-#if 0 // Disable editing region skies until the workflow is clear enough.
- // Add region presets.
- std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
- for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
- {
- std::string item_title = *it + " (" + region_name + ")";
- mSkyPresetCombo->add(item_title, LLWLParamKey(*it, LLEnvKey::SCOPE_REGION).toLLSD());
- }
- if (region_presets.size() > 0)
- {
- mSkyPresetCombo->addSeparator();
- }
-#endif
-
- // Add user presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
- if (user_presets.size() > 0)
- {
- mSkyPresetCombo->addSeparator();
- }
-
- // Add system presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
+ for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
+ {
+ mSkyPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
+ }
mSkyPresetCombo->setLabel(getString("combo_label"));
}
@@ -718,6 +547,7 @@ void LLFloaterEditSky::enableEditing(bool enable)
void LLFloaterEditSky::saveRegionSky()
{
+#if 0
LLWLParamKey key(getSelectedSkyPreset());
llassert(key.scope == LLEnvKey::SCOPE_REGION);
@@ -728,61 +558,55 @@ void LLFloaterEditSky::saveRegionSky()
// *TODO: save to cached region settings.
LL_WARNS("Windlight") << "Saving region sky is not fully implemented yet" << LL_ENDL;
+#endif
}
-LLWLParamKey LLFloaterEditSky::getSelectedSkyPreset()
+std::string LLFloaterEditSky::getSelectedPresetName() const
{
- LLWLParamKey key;
-
- if (mSkyPresetNameEditor->getVisible())
- {
- key.name = mSkyPresetNameEditor->getText();
- key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- LLSD combo_val = mSkyPresetCombo->getValue();
-
- if (!combo_val.isArray()) // manually typed text
- {
- key.name = combo_val.asString();
- key.scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- key.fromLLSD(combo_val);
- }
- }
+ std::string name;
+ if (mSkyPresetNameEditor->getVisible())
+ {
+ name = mSkyPresetNameEditor->getText();
+ }
+ else
+ {
+ LLSD combo_val = mSkyPresetCombo->getValue();
+ name = combo_val[0].asString();
+ }
- return key;
+ return name;
}
void LLFloaterEditSky::onSkyPresetNameEdited()
{
- // Disable saving a sky preset having empty name.
- LLWLParamKey key = getSelectedSkyPreset();
- mSaveButton->setEnabled(!key.name.empty());
+ std::string name = mSkyPresetNameEditor->getText();
+ LLSettingsWater::ptr_t psky = LLEnvironment::instance().getCurrentWater();
+
+ psky->setName(name);
}
void LLFloaterEditSky::onSkyPresetSelected()
{
- LLWLParamKey key = getSelectedSkyPreset();
- LLWLParamSet sky_params;
+ std::string name;
- if (!LLWLParamManager::instance().getParamSet(key, sky_params))
- {
- // Manually entered string?
- LL_WARNS("Windlight") << "No sky preset named " << key.toString() << LL_ENDL;
- return;
- }
+ name = getSelectedPresetName();
- LLEnvManagerNew::instance().useSkyParams(sky_params.getAll());
- //syncControls();
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().findSkyByName(name);
- bool can_edit = (key.scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings());
- enableEditing(can_edit);
+ if (!psky)
+ {
+ LL_WARNS("WATEREDIT") << "Could not find water preset" << LL_ENDL;
+ enableEditing(false);
+ return;
+ }
+
+ psky = psky->buildClone();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, psky);
+ mEditSettings = psky;
+
+ syncControls();
+ enableEditing(true);
- mMakeDefaultCheckBox->setEnabled(key.scope == LLEnvKey::SCOPE_LOCAL);
}
bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& response)
@@ -800,69 +624,29 @@ bool LLFloaterEditSky::onSaveAnswer(const LLSD& notification, const LLSD& respon
void LLFloaterEditSky::onSaveConfirmed()
{
- // Save current params to the selected preset.
- LLWLParamKey key(getSelectedSkyPreset());
+ // Save currently displayed water params to the selected preset.
+ std::string name = mEditSettings->getName();
- LL_DEBUGS("Windlight") << "Saving sky preset " << key.name << LL_ENDL;
- LLWLParamManager& wl_mgr = LLWLParamManager::instance();
- if (wl_mgr.hasParamSet(key))
- {
- wl_mgr.setParamSet(key, wl_mgr.mCurParams);
- }
- else
- {
- wl_mgr.addParamSet(key, wl_mgr.mCurParams);
- }
+ LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL;
- wl_mgr.savePreset(key);
+ LLEnvironment::instance().addSky(mEditSettings);
- // Change preference if requested.
- if (mMakeDefaultCheckBox->getValue())
- {
- LL_DEBUGS("Windlight") << key.name << " is now the new preferred sky preset" << LL_ENDL;
- LLEnvManagerNew::instance().setUseSkyPreset(key.name);
- }
+ // Change preference if requested.
+ if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue())
+ {
+ LL_DEBUGS("Windlight") << name << " is now the new preferred sky preset" << LL_ENDL;
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings);
+ }
- closeFloater();
+ closeFloater();
}
void LLFloaterEditSky::onBtnSave()
{
- LLWLParamKey selected_sky = getSelectedSkyPreset();
- LLWLParamManager& wl_mgr = LLWLParamManager::instance();
-
- if (selected_sky.scope == LLEnvKey::SCOPE_REGION)
- {
- saveRegionSky();
- closeFloater();
- return;
- }
+ LLEnvironment::instance().addSky(mEditSettings);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings);
- std::string name = selected_sky.name;
- if (name.empty())
- {
- // *TODO: show an alert
- LL_WARNS() << "Empty sky preset name" << LL_ENDL;
- return;
- }
-
- // Don't allow overwriting system presets.
- if (wl_mgr.isSystemPreset(name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
-
- // Save, ask for confirmation for overwriting an existing preset.
- if (wl_mgr.hasParamSet(selected_sky))
- {
- LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditSky::onSaveAnswer, this, _1, _2));
- }
- else
- {
- // new preset, hence no confirmation needed
- onSaveConfirmed();
- }
+ closeFloater();
}
void LLFloaterEditSky::onBtnCancel()
@@ -872,22 +656,12 @@ void LLFloaterEditSky::onBtnCancel()
void LLFloaterEditSky::onSkyPresetListChange()
{
- LLWLParamKey key = getSelectedSkyPreset(); // preset being edited
- if (!LLWLParamManager::instance().hasParamSet(key))
- {
- // Preset we've been editing doesn't exist anymore. Close the floater.
- closeFloater(false);
- }
- else
- {
- // A new preset has been added.
- // Refresh the presets list, though it may not make sense as the floater is about to be closed.
- refreshSkyPresetsList();
- }
+ refreshSkyPresetsList();
}
void LLFloaterEditSky::onRegionSettingsChange()
{
+#if 0
// If creating a new sky, don't bother.
if (isNewPreset())
{
@@ -905,10 +679,12 @@ void LLFloaterEditSky::onRegionSettingsChange()
{
refreshSkyPresetsList();
}
+#endif
}
void LLFloaterEditSky::onRegionInfoUpdate()
{
+#if 0
bool can_edit = true;
// If we've selected a region sky preset for editing.
@@ -919,4 +695,5 @@ void LLFloaterEditSky::onRegionInfoUpdate()
}
enableEditing(can_edit);
+#endif
}
diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h
deleted file mode 100644
index a06c4fc5fa..0000000000
--- a/indra/newview/llfloatereditsky.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @file llfloatereditsky.h
- * @brief Floater to create or edit a sky preset
- *
- * $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$
- */
-
-#ifndef LL_LLFLOATEREDITSKY_H
-#define LL_LLFLOATEREDITSKY_H
-
-#include "llfloater.h"
-#include "llwlparammanager.h"
-
-class LLButton;
-class LLCheckBoxCtrl;
-class LLComboBox;
-class LLLineEditor;
-
-/**
- * Floater for creating or editing a sky preset.
- */
-class LLFloaterEditSky : public LLFloater
-{
- LOG_CLASS(LLFloaterEditSky);
-
-public:
- LLFloaterEditSky(const LLSD &key);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
-
-private:
- void initCallbacks(void);
-
- //-- WL stuff begins ------------------------------------------------------
-
- void syncControls(); /// sync up sliders with parameters
-
- void setColorSwatch(const std::string& name, const WLColorControl& from_ctrl, F32 k);
-
- // general purpose callbacks for dealing with color controllers
- void onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl);
- void onColorControlRMoved(LLUICtrl* ctrl, void* userdata);
- void onColorControlGMoved(LLUICtrl* ctrl, void* userdata);
- void onColorControlBMoved(LLUICtrl* ctrl, void* userdata);
- void onFloatControlMoved(LLUICtrl* ctrl, void* userdata);
-
- // lighting callbacks for glow
- void onGlowRMoved(LLUICtrl* ctrl, void* userdata);
- void onGlowBMoved(LLUICtrl* ctrl, void* userdata);
-
- // lighting callbacks for sun
- void onSunMoved(LLUICtrl* ctrl, void* userdata);
- void onTimeChanged();
-
- // for handling when the star slider is moved to adjust the alpha
- void onStarAlphaMoved(LLUICtrl* ctrl);
-
- // handle cloud scrolling
- void onCloudScrollXMoved(LLUICtrl* ctrl);
- void onCloudScrollYMoved(LLUICtrl* ctrl);
- void onCloudScrollXToggled(LLUICtrl* ctrl);
- void onCloudScrollYToggled(LLUICtrl* ctrl);
-
- //-- WL stuff ends --------------------------------------------------------
-
- void reset(); /// reset the floater to its initial state
- bool isNewPreset() const;
- void refreshSkyPresetsList();
- void enableEditing(bool enable);
- void saveRegionSky();
- LLWLParamKey getSelectedSkyPreset();
-
- void onSkyPresetNameEdited();
- void onSkyPresetSelected();
- bool onSaveAnswer(const LLSD& notification, const LLSD& response);
- void onSaveConfirmed();
-
- void onBtnSave();
- void onBtnCancel();
-
- void onSkyPresetListChange();
- void onRegionSettingsChange();
- void onRegionInfoUpdate();
-
- LLLineEditor* mSkyPresetNameEditor;
- LLComboBox* mSkyPresetCombo;
- LLCheckBoxCtrl* mMakeDefaultCheckBox;
- LLButton* mSaveButton;
-};
-
-#endif // LL_LLFLOATEREDITSKY_H
diff --git a/indra/newview/llfloatereditwater.cpp b/indra/newview/llfloatereditwater.cpp
index 43b44eae37..6e7b777e70 100644
--- a/indra/newview/llfloatereditwater.cpp
+++ b/indra/newview/llfloatereditwater.cpp
@@ -28,6 +28,8 @@
#include "llfloatereditwater.h"
+#include <boost/make_shared.hpp>
+
// libs
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -42,16 +44,22 @@
#include "llagent.h"
#include "llregioninfomodel.h"
#include "llviewerregion.h"
-#include "llwaterparammanager.h"
+
+#include "llenvironment.h"
+#include "llsettingswater.h"
+#include "llenvadapters.h"
+
+#include "v3colorutil.h"
#undef max // Fixes a Windows compiler error
-LLFloaterEditWater::LLFloaterEditWater(const LLSD &key)
-: LLFloater(key)
-, mWaterPresetNameEditor(NULL)
-, mWaterPresetCombo(NULL)
-, mMakeDefaultCheckBox(NULL)
-, mSaveButton(NULL)
+LLFloaterEditWater::LLFloaterEditWater(const LLSD &key):
+ LLFloater(key),
+ mWaterPresetNameEditor(NULL),
+ mWaterPresetCombo(NULL),
+ mMakeDefaultCheckBox(NULL),
+ mSaveButton(NULL),
+ mWaterAdapter()
{
}
@@ -63,6 +71,10 @@ BOOL LLFloaterEditWater::postBuild()
mMakeDefaultCheckBox = getChild<LLCheckBoxCtrl>("make_default_cb");
mSaveButton = getChild<LLButton>("save");
+ mWaterAdapter = boost::make_shared<LLWatterSettingsAdapter>();
+
+ LLEnvironment::instance().setWaterListChange(boost::bind(&LLFloaterEditWater::onWaterPresetListChange, this));
+
initCallbacks();
refreshWaterPresetsList();
syncControls();
@@ -99,7 +111,8 @@ void LLFloaterEditWater::onClose(bool app_quitting)
{
if (!app_quitting) // there's no point to change environment if we're quitting
{
- LLEnvManagerNew::instance().usePrefs(); // revert changes made to current environment
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
}
}
@@ -119,44 +132,38 @@ void LLFloaterEditWater::initCallbacks(void)
mSaveButton->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnSave, this));
getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterEditWater::onBtnCancel, this));
- LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditWater::onRegionSettingsChange, this));
- LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEditWater::onWaterPresetListChange, this));
-
// Connect to region info updates.
LLRegionInfoModel::instance().setUpdateCallback(boost::bind(&LLFloaterEditWater::onRegionInfoUpdate, this));
//-------------------------------------------------------------------------
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
-
- getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterEditWater::onWaterFogColorMoved, this, _1, &water_mgr.mFogColor));
- //getChild<LLUICtrl>("WaterGlow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onColorControlAMoved, this, _1, &water_mgr.mFogColor));
+ getChild<LLUICtrl>("WaterFogColor")->setCommitCallback(boost::bind(&LLFloaterEditWater::onColorControlMoved, this, _1, &mWaterAdapter->mFogColor));
// fog density
- getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterEditWater::onExpFloatControlMoved, this, _1, &water_mgr.mFogDensity));
- getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mUnderWaterFogMod));
+ getChild<LLUICtrl>("WaterFogDensity")->setCommitCallback(boost::bind(&LLFloaterEditWater::onExpFloatControlMoved, this, _1, &mWaterAdapter->mFogDensity));
+ getChild<LLUICtrl>("WaterUnderWaterFogMod")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mUnderWaterFogMod));
// blue density
- getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlXMoved, this, _1, &water_mgr.mNormalScale));
- getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlYMoved, this, _1, &water_mgr.mNormalScale));
- getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlZMoved, this, _1, &water_mgr.mNormalScale));
+ getChild<LLUICtrl>("WaterNormalScaleX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlXMoved, this, _1, &mWaterAdapter->mNormalScale));
+ getChild<LLUICtrl>("WaterNormalScaleY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlYMoved, this, _1, &mWaterAdapter->mNormalScale));
+ getChild<LLUICtrl>("WaterNormalScaleZ")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector3ControlZMoved, this, _1, &mWaterAdapter->mNormalScale));
// fresnel
- getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelScale));
- getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mFresnelOffset));
+ getChild<LLUICtrl>("WaterFresnelScale")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mFresnelScale));
+ getChild<LLUICtrl>("WaterFresnelOffset")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mFresnelOffset));
// scale above/below
- getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleAbove));
- getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mScaleBelow));
+ getChild<LLUICtrl>("WaterScaleAbove")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mScaleAbove));
+ getChild<LLUICtrl>("WaterScaleBelow")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mScaleBelow));
// blur mult
- getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &water_mgr.mBlurMultiplier));
+ getChild<LLUICtrl>("WaterBlurMult")->setCommitCallback(boost::bind(&LLFloaterEditWater::onFloatControlMoved, this, _1, &mWaterAdapter->mBlurMultiplier));
// wave direction
- getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave1Dir));
- getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave1Dir));
- getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &water_mgr.mWave2Dir));
- getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &water_mgr.mWave2Dir));
+ getChild<LLUICtrl>("WaterWave1DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &mWaterAdapter->mWave1Dir));
+ getChild<LLUICtrl>("WaterWave1DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &mWaterAdapter->mWave1Dir));
+ getChild<LLUICtrl>("WaterWave2DirX")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlXMoved, this, _1, &mWaterAdapter->mWave2Dir));
+ getChild<LLUICtrl>("WaterWave2DirY")->setCommitCallback(boost::bind(&LLFloaterEditWater::onVector2ControlYMoved, this, _1, &mWaterAdapter->mWave2Dir));
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("WaterNormalMap");
texture_ctrl->setDefaultImageAssetID(DEFAULT_WATER_NORMAL);
@@ -169,304 +176,132 @@ void LLFloaterEditWater::syncControls()
{
// *TODO: Eliminate slow getChild() calls.
- bool err;
-
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
-
- LLWaterParamSet& current_params = water_mgr.mCurParams;
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mEditSettings = pwater;
- // blue horizon
- water_mgr.mFogColor = current_params.getVector4(water_mgr.mFogColor.mName, err);
+ std::string name = pwater->getName();
+ mWaterPresetNameEditor->setText(name);
+ mWaterPresetCombo->setValue(name);
- LLColor4 col = water_mgr.getFogColor();
//getChild<LLUICtrl>("WaterGlow")->setValue(col.mV[3]);
- col.mV[3] = 1.0f;
- getChild<LLColorSwatchCtrl>("WaterFogColor")->set(col);
+ getChild<LLColorSwatchCtrl>("WaterFogColor")->set(LLColor4(pwater->getWaterFogColor()));
// fog and wavelets
- water_mgr.mFogDensity.mExp =
- log(current_params.getFloat(water_mgr.mFogDensity.mName, err)) /
- log(water_mgr.mFogDensity.mBase);
- water_mgr.setDensitySliderValue(water_mgr.mFogDensity.mExp);
- getChild<LLUICtrl>("WaterFogDensity")->setValue(water_mgr.mFogDensity.mExp);
+ mWaterAdapter->mFogDensity = pwater->getWaterFogDensity();
+ getChild<LLUICtrl>("WaterFogDensity")->setValue(mWaterAdapter->mFogDensity.getExp());
- water_mgr.mUnderWaterFogMod.mX =
- current_params.getFloat(water_mgr.mUnderWaterFogMod.mName, err);
- getChild<LLUICtrl>("WaterUnderWaterFogMod")->setValue(water_mgr.mUnderWaterFogMod.mX);
+ mWaterAdapter->mUnderWaterFogMod = pwater->getFogMod();
+ getChild<LLUICtrl>("WaterUnderWaterFogMod")->setValue(static_cast<F32>(mWaterAdapter->mUnderWaterFogMod));
- water_mgr.mNormalScale = current_params.getVector3(water_mgr.mNormalScale.mName, err);
- getChild<LLUICtrl>("WaterNormalScaleX")->setValue(water_mgr.mNormalScale.mX);
- getChild<LLUICtrl>("WaterNormalScaleY")->setValue(water_mgr.mNormalScale.mY);
- getChild<LLUICtrl>("WaterNormalScaleZ")->setValue(water_mgr.mNormalScale.mZ);
+ mWaterAdapter->mNormalScale = pwater->getNormalScale();
+ getChild<LLUICtrl>("WaterNormalScaleX")->setValue(mWaterAdapter->mNormalScale.getX());
+ getChild<LLUICtrl>("WaterNormalScaleY")->setValue(mWaterAdapter->mNormalScale.getY());
+ getChild<LLUICtrl>("WaterNormalScaleZ")->setValue(mWaterAdapter->mNormalScale.getZ());
// Fresnel
- water_mgr.mFresnelScale.mX = current_params.getFloat(water_mgr.mFresnelScale.mName, err);
- getChild<LLUICtrl>("WaterFresnelScale")->setValue(water_mgr.mFresnelScale.mX);
- water_mgr.mFresnelOffset.mX = current_params.getFloat(water_mgr.mFresnelOffset.mName, err);
- getChild<LLUICtrl>("WaterFresnelOffset")->setValue(water_mgr.mFresnelOffset.mX);
+ mWaterAdapter->mFresnelScale = pwater->getFresnelScale();
+ getChild<LLUICtrl>("WaterFresnelScale")->setValue(static_cast<F32>(mWaterAdapter->mFresnelScale));
+ mWaterAdapter->mFresnelOffset = pwater->getFresnelOffset();
+ getChild<LLUICtrl>("WaterFresnelOffset")->setValue(static_cast<F32>(mWaterAdapter->mFresnelOffset));
// Scale Above/Below
- water_mgr.mScaleAbove.mX = current_params.getFloat(water_mgr.mScaleAbove.mName, err);
- getChild<LLUICtrl>("WaterScaleAbove")->setValue(water_mgr.mScaleAbove.mX);
- water_mgr.mScaleBelow.mX = current_params.getFloat(water_mgr.mScaleBelow.mName, err);
- getChild<LLUICtrl>("WaterScaleBelow")->setValue(water_mgr.mScaleBelow.mX);
+ mWaterAdapter->mScaleAbove = pwater->getScaleAbove();
+ getChild<LLUICtrl>("WaterScaleAbove")->setValue(static_cast<F32>(mWaterAdapter->mScaleAbove));
+ mWaterAdapter->mScaleBelow = pwater->getScaleBelow();
+ getChild<LLUICtrl>("WaterScaleBelow")->setValue(static_cast<F32>(mWaterAdapter->mScaleBelow));
// blur mult
- water_mgr.mBlurMultiplier.mX = current_params.getFloat(water_mgr.mBlurMultiplier.mName, err);
- getChild<LLUICtrl>("WaterBlurMult")->setValue(water_mgr.mBlurMultiplier.mX);
+ mWaterAdapter->mBlurMultiplier = pwater->getBlurMultiplier();
+ getChild<LLUICtrl>("WaterBlurMult")->setValue(static_cast<F32>(mWaterAdapter->mBlurMultiplier));
// wave directions
- water_mgr.mWave1Dir = current_params.getVector2(water_mgr.mWave1Dir.mName, err);
- getChild<LLUICtrl>("WaterWave1DirX")->setValue(water_mgr.mWave1Dir.mX);
- getChild<LLUICtrl>("WaterWave1DirY")->setValue(water_mgr.mWave1Dir.mY);
+ mWaterAdapter->mWave1Dir = pwater->getWave1Dir();
+ getChild<LLUICtrl>("WaterWave1DirX")->setValue(mWaterAdapter->mWave1Dir.getU());
+ getChild<LLUICtrl>("WaterWave1DirY")->setValue(mWaterAdapter->mWave1Dir.getV());
- water_mgr.mWave2Dir = current_params.getVector2(water_mgr.mWave2Dir.mName, err);
- getChild<LLUICtrl>("WaterWave2DirX")->setValue(water_mgr.mWave2Dir.mX);
- getChild<LLUICtrl>("WaterWave2DirY")->setValue(water_mgr.mWave2Dir.mY);
+ mWaterAdapter->mWave2Dir = pwater->getWave2Dir();
+ getChild<LLUICtrl>("WaterWave2DirX")->setValue(mWaterAdapter->mWave2Dir.getU());
+ getChild<LLUICtrl>("WaterWave2DirY")->setValue(mWaterAdapter->mWave2Dir.getV());
LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("WaterNormalMap");
- textCtrl->setImageAssetID(water_mgr.getNormalMapID());
-}
-
-// color control callbacks
-void LLFloaterEditWater::onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
-{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- color_ctrl->mR = sldr_ctrl->getValueF32();
-
- // move i if it's the max
- if (color_ctrl->mR >= color_ctrl->mG
- && color_ctrl->mR >= color_ctrl->mB
- && color_ctrl->mHasSliderName)
- {
- color_ctrl->mI = color_ctrl->mR;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- getChild<LLUICtrl>(name)->setValue(color_ctrl->mR);
- }
-
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
-}
-
-void LLFloaterEditWater::onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
-{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- color_ctrl->mG = sldr_ctrl->getValueF32();
-
- // move i if it's the max
- if (color_ctrl->mG >= color_ctrl->mR
- && color_ctrl->mG >= color_ctrl->mB
- && color_ctrl->mHasSliderName)
- {
- color_ctrl->mI = color_ctrl->mG;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- getChild<LLUICtrl>(name)->setValue(color_ctrl->mG);
-
- }
-
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
-}
-
-void LLFloaterEditWater::onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
-{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- color_ctrl->mB = sldr_ctrl->getValueF32();
-
- // move i if it's the max
- if (color_ctrl->mB >= color_ctrl->mR
- && color_ctrl->mB >= color_ctrl->mG
- && color_ctrl->mHasSliderName)
- {
- color_ctrl->mI = color_ctrl->mB;
- std::string name = color_ctrl->mSliderName;
- name.append("I");
-
- getChild<LLUICtrl>(name)->setValue(color_ctrl->mB);
- }
-
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
-}
-
-void LLFloaterEditWater::onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
-{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- color_ctrl->mA = sldr_ctrl->getValueF32();
-
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
+ textCtrl->setImageAssetID(pwater->getNormalMapID());
}
-void LLFloaterEditWater::onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
-{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- color_ctrl->mI = sldr_ctrl->getValueF32();
-
- // only for sliders where we pass a name
- if (color_ctrl->mHasSliderName)
- {
- // set it to the top
- F32 maxVal = std::max(std::max(color_ctrl->mR, color_ctrl->mG), color_ctrl->mB);
- F32 iVal;
-
- iVal = color_ctrl->mI;
-
- // get the names of the other sliders
- std::string rName = color_ctrl->mSliderName;
- rName.append("R");
- std::string gName = color_ctrl->mSliderName;
- gName.append("G");
- std::string bName = color_ctrl->mSliderName;
- bName.append("B");
-
- // handle if at 0
- if (iVal == 0)
- {
- color_ctrl->mR = 0;
- color_ctrl->mG = 0;
- color_ctrl->mB = 0;
-
- // if all at the start
- // set them all to the intensity
- }
- else if (maxVal == 0)
- {
- color_ctrl->mR = iVal;
- color_ctrl->mG = iVal;
- color_ctrl->mB = iVal;
- }
- else
- {
- // add delta amounts to each
- F32 delta = (iVal - maxVal) / maxVal;
- color_ctrl->mR *= (1.0f + delta);
- color_ctrl->mG *= (1.0f + delta);
- color_ctrl->mB *= (1.0f + delta);
- }
-
- // set the sliders to the new vals
- getChild<LLUICtrl>(rName)->setValue(color_ctrl->mR);
- getChild<LLUICtrl>(gName)->setValue(color_ctrl->mG);
- getChild<LLUICtrl>(bName)->setValue(color_ctrl->mB);
- }
-
- // now update the current parameters and send them to shaders
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
- LLWaterParamManager::getInstance()->propagateParameters();
-}
-
// vector control callbacks
-void LLFloaterEditWater::onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
+void LLFloaterEditWater::onVector3ControlXMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl)
{
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- vector_ctrl->mX = sldr_ctrl->getValueF32();
-
- vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
+ vector_ctrl->setX( sldr_ctrl->getValueF32() );
+ vector_ctrl->update(mEditSettings);
}
// vector control callbacks
-void LLFloaterEditWater::onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
+void LLFloaterEditWater::onVector3ControlYMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl)
{
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- vector_ctrl->mY = sldr_ctrl->getValueF32();
-
- vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
+ vector_ctrl->setY(sldr_ctrl->getValueF32());
+ vector_ctrl->update(mEditSettings);
}
// vector control callbacks
-void LLFloaterEditWater::onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl)
+void LLFloaterEditWater::onVector3ControlZMoved(LLUICtrl* ctrl, WLVect3Control* vector_ctrl)
{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- vector_ctrl->mZ = sldr_ctrl->getValueF32();
-
- vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- LLWaterParamManager::getInstance()->propagateParameters();
+ vector_ctrl->setZ(sldr_ctrl->getValueF32());
+ vector_ctrl->update(mEditSettings);
}
// vector control callbacks
-void LLFloaterEditWater::onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl)
+void LLFloaterEditWater::onVector2ControlXMoved(LLUICtrl* ctrl, WLVect2Control* vector_ctrl)
{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
-
- vector_ctrl->mX = sldr_ctrl->getValueF32();
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
+ vector_ctrl->setU(sldr_ctrl->getValueF32());
+ vector_ctrl->update(mEditSettings);
}
// vector control callbacks
-void LLFloaterEditWater::onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl)
+void LLFloaterEditWater::onVector2ControlYMoved(LLUICtrl* ctrl, WLVect2Control* vector_ctrl)
{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- vector_ctrl->mY = sldr_ctrl->getValueF32();
-
- vector_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
-
- LLWaterParamManager::getInstance()->propagateParameters();
+ vector_ctrl->setV(sldr_ctrl->getValueF32());
+ vector_ctrl->update(mEditSettings);
}
-void LLFloaterEditWater::onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl)
+void LLFloaterEditWater::onFloatControlMoved(LLUICtrl* ctrl, WLFloatControl* floatControl)
{
- LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
+ LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- floatControl->mX = sldr_ctrl->getValueF32() / floatControl->mMult;
-
- floatControl->update(LLWaterParamManager::getInstance()->mCurParams);
- LLWaterParamManager::getInstance()->propagateParameters();
+ floatControl->setValue(sldr_ctrl->getValueF32());
+ floatControl->update(mEditSettings);
}
-void LLFloaterEditWater::onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl)
+void LLFloaterEditWater::onExpFloatControlMoved(LLUICtrl* ctrl, WLXFloatControl* expFloatControl)
{
LLSliderCtrl* sldr_ctrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 val = sldr_ctrl->getValueF32();
- expFloatControl->mExp = val;
- LLWaterParamManager::getInstance()->setDensitySliderValue(val);
-
- expFloatControl->update(LLWaterParamManager::getInstance()->mCurParams);
- LLWaterParamManager::getInstance()->propagateParameters();
+ expFloatControl->setExp(sldr_ctrl->getValueF32());
+ expFloatControl->update(mEditSettings);
}
-void LLFloaterEditWater::onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl)
+void LLFloaterEditWater::onColorControlMoved(LLUICtrl* ctrl, WLColorControl* color_ctrl)
{
LLColorSwatchCtrl* swatch = static_cast<LLColorSwatchCtrl*>(ctrl);
- *color_ctrl = swatch->get();
-
- color_ctrl->update(LLWaterParamManager::getInstance()->mCurParams);
- LLWaterParamManager::getInstance()->propagateParameters();
+ color_ctrl->setColor4( swatch->get() );
+ color_ctrl->update(mEditSettings);
}
void LLFloaterEditWater::onNormalMapPicked(LLUICtrl* ctrl)
{
LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(ctrl);
LLUUID textID = textCtrl->getImageAssetID();
- LLWaterParamManager::getInstance()->setNormalMapID(textID);
+ mEditSettings->setNormalMapID(textID);
}
//=============================================================================
@@ -496,38 +331,12 @@ void LLFloaterEditWater::refreshWaterPresetsList()
{
mWaterPresetCombo->removeall();
-#if 0 // *TODO: enable when we have a clear workflow to edit existing region environment
- // If the region already has water params, add them to the list.
- const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings();
- if (region_settings.getWaterParams().size() != 0)
- {
- const std::string& region_name = gAgent.getRegion()->getName();
- mWaterPresetCombo->add(region_name, LLSD().with(0, region_name).with(1, LLEnvKey::SCOPE_REGION));
- mWaterPresetCombo->addSeparator();
- }
-#endif
-
- std::list<std::string> user_presets, system_presets;
- LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);
+ LLEnvironment::list_name_id_t list = LLEnvironment::instance().getWaterList();
- // Add local user presets first.
- for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- const std::string& name = *it;
- mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>]
- }
-
- if (user_presets.size() > 0)
- {
- mWaterPresetCombo->addSeparator();
- }
-
- // Add local system presets.
- for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it)
- {
- const std::string& name = *it;
- mWaterPresetCombo->add(name, LLSD().with(0, name).with(1, LLEnvKey::SCOPE_LOCAL)); // [<name>, <scope>]
- }
+ for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
+ {
+ mWaterPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
+ }
mWaterPresetCombo->setLabel(getString("combo_label"));
}
@@ -544,6 +353,7 @@ void LLFloaterEditWater::enableEditing(bool enable)
void LLFloaterEditWater::saveRegionWater()
{
+#if 0
llassert(getCurrentScope() == LLEnvKey::SCOPE_REGION); // make sure we're editing region water
LL_DEBUGS("Windlight") << "Saving region water preset" << LL_ENDL;
@@ -552,8 +362,10 @@ void LLFloaterEditWater::saveRegionWater()
// *TODO: save to cached region settings.
LL_WARNS("Windlight") << "Saving region water is not fully implemented yet" << LL_ENDL;
+#endif
}
+#if 0
std::string LLFloaterEditWater::getCurrentPresetName() const
{
std::string name;
@@ -561,7 +373,9 @@ std::string LLFloaterEditWater::getCurrentPresetName() const
getSelectedPreset(name, scope);
return name;
}
+#endif
+#if 0
LLEnvKey::EScope LLFloaterEditWater::getCurrentScope() const
{
std::string name;
@@ -569,71 +383,62 @@ LLEnvKey::EScope LLFloaterEditWater::getCurrentScope() const
getSelectedPreset(name, scope);
return scope;
}
+#endif
-void LLFloaterEditWater::getSelectedPreset(std::string& name, LLEnvKey::EScope& scope) const
+std::string LLFloaterEditWater::getSelectedPresetName() const
{
+ std::string name;
if (mWaterPresetNameEditor->getVisible())
{
name = mWaterPresetNameEditor->getText();
- scope = LLEnvKey::SCOPE_LOCAL;
}
else
{
LLSD combo_val = mWaterPresetCombo->getValue();
-
- if (!combo_val.isArray()) // manually typed text
- {
- name = combo_val.asString();
- scope = LLEnvKey::SCOPE_LOCAL;
- }
- else
- {
- name = combo_val[0].asString();
- scope = (LLEnvKey::EScope) combo_val[1].asInteger();
- }
+ name = combo_val[0].asString();
}
+
+ return name;
}
void LLFloaterEditWater::onWaterPresetNameEdited()
{
+ std::string name = mWaterPresetNameEditor->getText();
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+
+ pwater->setName(name);
+#if 0
// Disable saving a water preset having empty name.
mSaveButton->setEnabled(!getCurrentPresetName().empty());
+#endif
}
void LLFloaterEditWater::onWaterPresetSelected()
{
- LLWaterParamSet water_params;
std::string name;
- LLEnvKey::EScope scope;
- getSelectedPreset(name, scope);
+ name = getSelectedPresetName();
- // Display selected preset.
- if (scope == LLEnvKey::SCOPE_REGION)
- {
- water_params.setAll(LLEnvManagerNew::instance().getRegionSettings().getWaterParams());
- }
- else // local preset selected
- {
- if (!LLWaterParamManager::instance().getParamSet(name, water_params))
- {
- // Manually entered string?
- LL_WARNS("Windlight") << "No water preset named " << name << LL_ENDL;
- return;
- }
- }
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().findWaterByName(name);
- LLEnvManagerNew::instance().useWaterParams(water_params.getAll());
+ if (!pwater)
+ {
+ LL_WARNS("WATEREDIT") << "Could not find water preset" << LL_ENDL;
+ enableEditing(false);
+ return;
+ }
- bool can_edit = (scope == LLEnvKey::SCOPE_LOCAL || LLEnvManagerNew::canEditRegionSettings());
- enableEditing(can_edit);
+ pwater = pwater->buildClone();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, pwater);
+ mEditSettings = pwater;
- mMakeDefaultCheckBox->setEnabled(scope == LLEnvKey::SCOPE_LOCAL);
+ syncControls();
+ enableEditing(true);
}
bool LLFloaterEditWater::onSaveAnswer(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
// If they choose save, do it. Otherwise, don't do anything
if (option == 0)
@@ -641,32 +446,23 @@ bool LLFloaterEditWater::onSaveAnswer(const LLSD& notification, const LLSD& resp
onSaveConfirmed();
}
- return false;
+ return false;
}
void LLFloaterEditWater::onSaveConfirmed()
{
// Save currently displayed water params to the selected preset.
- std::string name = getCurrentPresetName();
+ std::string name = mEditSettings->getName();
LL_DEBUGS("Windlight") << "Saving sky preset " << name << LL_ENDL;
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- if (water_mgr.hasParamSet(name))
- {
- water_mgr.setParamSet(name, water_mgr.mCurParams);
- }
- else
- {
- water_mgr.addParamSet(name, water_mgr.mCurParams);
- }
- water_mgr.savePreset(name);
+ LLEnvironment::instance().addWater(mEditSettings);
// Change preference if requested.
if (mMakeDefaultCheckBox->getEnabled() && mMakeDefaultCheckBox->getValue())
{
LL_DEBUGS("Windlight") << name << " is now the new preferred water preset" << LL_ENDL;
- LLEnvManagerNew::instance().setUseWaterPreset(name);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings);
}
closeFloater();
@@ -674,42 +470,10 @@ void LLFloaterEditWater::onSaveConfirmed()
void LLFloaterEditWater::onBtnSave()
{
- LLEnvKey::EScope scope;
- std::string name;
- getSelectedPreset(name, scope);
-
- if (scope == LLEnvKey::SCOPE_REGION)
- {
- saveRegionWater();
- closeFloater();
- return;
- }
-
- if (name.empty())
- {
- // *TODO: show an alert
- LL_WARNS() << "Empty water preset name" << LL_ENDL;
- return;
- }
-
- // Don't allow overwriting system presets.
- LLWaterParamManager& water_mgr = LLWaterParamManager::instance();
- if (water_mgr.isSystemPreset(name))
- {
- LLNotificationsUtil::add("WLNoEditDefault");
- return;
- }
+ LLEnvironment::instance().addWater(mEditSettings);
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mEditSettings);
- // Save, ask for confirmation for overwriting an existing preset.
- if (water_mgr.hasParamSet(name))
- {
- LLNotificationsUtil::add("WLSavePresetAlert", LLSD(), LLSD(), boost::bind(&LLFloaterEditWater::onSaveAnswer, this, _1, _2));
- }
- else
- {
- // new preset, hence no confirmation needed
- onSaveConfirmed();
- }
+ closeFloater();
}
void LLFloaterEditWater::onBtnCancel()
@@ -719,25 +483,12 @@ void LLFloaterEditWater::onBtnCancel()
void LLFloaterEditWater::onWaterPresetListChange()
{
- std::string name;
- LLEnvKey::EScope scope;
- getSelectedPreset(name, scope); // preset being edited
-
- if (scope == LLEnvKey::SCOPE_LOCAL && !LLWaterParamManager::instance().hasParamSet(name))
- {
- // Preset we've been editing doesn't exist anymore. Close the floater.
- closeFloater(false);
- }
- else
- {
- // A new preset has been added.
- // Refresh the presets list, though it may not make sense as the floater is about to be closed.
- refreshWaterPresetsList();
- }
+ refreshWaterPresetsList();
}
void LLFloaterEditWater::onRegionSettingsChange()
{
+#if 0
// If creating a new preset, don't bother.
if (isNewPreset())
{
@@ -755,10 +506,12 @@ void LLFloaterEditWater::onRegionSettingsChange()
{
refreshWaterPresetsList();
}
+#endif
}
void LLFloaterEditWater::onRegionInfoUpdate()
{
+#if 0
bool can_edit = true;
// If we've selected the region water for editing.
@@ -769,4 +522,5 @@ void LLFloaterEditWater::onRegionInfoUpdate()
}
enableEditing(can_edit);
+#endif
}
diff --git a/indra/newview/llfloatereditwater.h b/indra/newview/llfloatereditwater.h
deleted file mode 100644
index 2211bca59f..0000000000
--- a/indra/newview/llfloatereditwater.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * @file llfloatereditwater.h
- * @brief Floater to create or edit a water preset
- *
- * $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$
- */
-
-#ifndef LL_LLFLOATEREDITWATER_H
-#define LL_LLFLOATEREDITWATER_H
-
-#include "llfloater.h"
-#include "llenvmanager.h" // for LLEnvKey
-
-class LLButton;
-class LLCheckBoxCtrl;
-class LLComboBox;
-class LLLineEditor;
-
-struct WaterVector2Control;
-struct WaterVector3Control;
-struct WaterColorControl;
-struct WaterFloatControl;
-struct WaterExpFloatControl;
-
-class LLFloaterEditWater : public LLFloater
-{
- LOG_CLASS(LLFloaterEditWater);
-
-public:
- LLFloaterEditWater(const LLSD &key);
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void draw();
-
-private:
- void initCallbacks(void);
-
- //-- WL stuff begins ------------------------------------------------------
-
- void syncControls(); /// sync up sliders with parameters
-
- // general purpose callbacks for dealing with color controllers
- void onColorControlRMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
- void onColorControlGMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
- void onColorControlBMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
- void onColorControlAMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
- void onColorControlIMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
-
- void onVector3ControlXMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl);
- void onVector3ControlYMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl);
- void onVector3ControlZMoved(LLUICtrl* ctrl, WaterVector3Control* vector_ctrl);
-
- void onVector2ControlXMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl);
- void onVector2ControlYMoved(LLUICtrl* ctrl, WaterVector2Control* vector_ctrl);
-
- void onFloatControlMoved(LLUICtrl* ctrl, WaterFloatControl* floatControl);
-
- void onExpFloatControlMoved(LLUICtrl* ctrl, WaterExpFloatControl* expFloatControl);
-
- void onWaterFogColorMoved(LLUICtrl* ctrl, WaterColorControl* color_ctrl);
-
- void onNormalMapPicked(LLUICtrl* ctrl); /// handle if they choose a new normal map
-
- //-- WL stuff ends --------------------------------------------------------
-
- void reset();
- bool isNewPreset() const;
- void refreshWaterPresetsList();
- void enableEditing(bool enable);
- void saveRegionWater();
-
- std::string getCurrentPresetName() const;
- LLEnvKey::EScope getCurrentScope() const;
- void getSelectedPreset(std::string& name, LLEnvKey::EScope& scope) const;
-
- void onWaterPresetNameEdited();
- void onWaterPresetSelected();
- bool onSaveAnswer(const LLSD& notification, const LLSD& response);
- void onSaveConfirmed();
-
- void onBtnSave();
- void onBtnCancel();
-
- void onWaterPresetListChange();
- void onRegionSettingsChange();
- void onRegionInfoUpdate();
-
- LLLineEditor* mWaterPresetNameEditor;
- LLComboBox* mWaterPresetCombo;
- LLCheckBoxCtrl* mMakeDefaultCheckBox;
- LLButton* mSaveButton;
-};
-
-#endif // LL_LLFLOATEREDITWATER_H
diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp
new file mode 100644
index 0000000000..95d6a2d652
--- /dev/null
+++ b/indra/newview/llfloaterenvironmentadjust.cpp
@@ -0,0 +1,482 @@
+/**
+ * @file llfloaterfixedenvironment.cpp
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterenvironmentadjust.h"
+
+#include "llnotificationsutil.h"
+#include "llslider.h"
+#include "llsliderctrl.h"
+#include "llcolorswatch.h"
+#include "lltexturectrl.h"
+#include "llvirtualtrackball.h"
+#include "llenvironment.h"
+#include "llviewercontrol.h"
+
+//=========================================================================
+namespace
+{
+ const std::string FIELD_SKY_AMBIENT_LIGHT("ambient_light");
+ const std::string FIELD_SKY_BLUE_HORIZON("blue_horizon");
+ const std::string FIELD_SKY_BLUE_DENSITY("blue_density");
+ const std::string FIELD_SKY_SUN_COLOR("sun_color");
+ const std::string FIELD_SKY_CLOUD_COLOR("cloud_color");
+ const std::string FIELD_SKY_HAZE_HORIZON("haze_horizon");
+ const std::string FIELD_SKY_HAZE_DENSITY("haze_density");
+ const std::string FIELD_SKY_CLOUD_COVERAGE("cloud_coverage");
+ const std::string FIELD_SKY_CLOUD_MAP("cloud_map");
+ const std::string FIELD_WATER_NORMAL_MAP("water_normal_map");
+ const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale");
+ const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma");
+ const std::string FIELD_SKY_SUN_ROTATION("sun_rotation");
+ const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
+ const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");
+ const std::string FIELD_SKY_SUN_SCALE("sun_scale");
+ const std::string FIELD_SKY_GLOW_FOCUS("glow_focus");
+ const std::string FIELD_SKY_GLOW_SIZE("glow_size");
+ const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
+ const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
+ const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
+ const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
+ const std::string BTN_RESET("btn_reset");
+
+ 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);
+ const F32 SLIDER_SCALE_GLOW_B(-5.0f);
+ //const F32 SLIDER_SCALE_DENSITY_MULTIPLIER(0.001f);
+
+ const S32 FLOATER_ENVIRONMENT_UPDATE(-2);
+}
+
+//=========================================================================
+LLFloaterEnvironmentAdjust::LLFloaterEnvironmentAdjust(const LLSD &key):
+ LLFloater(key)
+{}
+
+LLFloaterEnvironmentAdjust::~LLFloaterEnvironmentAdjust()
+{}
+
+//-------------------------------------------------------------------------
+BOOL LLFloaterEnvironmentAdjust::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_AMBIENT_LIGHT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAmbientLightChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_BLUE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueHorizonChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_BLUE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeHorizonChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSceneGammaChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudColorChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudCoverageChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunColorChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+ getChild<LLUICtrl>(BTN_RESET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onButtonReset(); });
+
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); });
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setDefaultImageAssetID(LLSettingsSky::GetDefaultCloudNoiseTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setAllowNoTexture(TRUE);
+
+ getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId());
+ getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture")));
+ getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); });
+
+ refresh();
+ return TRUE;
+}
+
+void LLFloaterEnvironmentAdjust::onOpen(const LLSD& key)
+{
+ if (!mLiveSky)
+ {
+ LLEnvironment::instance().saveBeaconsState();
+ }
+ captureCurrentEnvironment();
+
+ mEventConnection = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32 version){ onEnvironmentUpdated(env, version); });
+
+ LLFloater::onOpen(key);
+ refresh();
+}
+
+void LLFloaterEnvironmentAdjust::onClose(bool app_quitting)
+{
+ LLEnvironment::instance().revertBeaconsState();
+ mEventConnection.disconnect();
+ mLiveSky.reset();
+ mLiveWater.reset();
+ LLFloater::onClose(app_quitting);
+}
+
+
+//-------------------------------------------------------------------------
+void LLFloaterEnvironmentAdjust::refresh()
+{
+ if (!mLiveSky || !mLiveWater)
+ {
+ setAllChildrenEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->set(mLiveSky->getAmbientColor() / SLIDER_SCALE_SUN_AMBIENT);
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->set(mLiveSky->getBlueHorizon() / SLIDER_SCALE_BLUE_HORIZON_DENSITY);
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->set(mLiveSky->getBlueDensity() / SLIDER_SCALE_BLUE_HORIZON_DENSITY);
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setValue(mLiveSky->getHazeHorizon());
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setValue(mLiveSky->getHazeDensity());
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setValue(mLiveSky->getGamma());
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->set(mLiveSky->getCloudColor());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setValue(mLiveSky->getCloudShadow());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setValue(mLiveSky->getCloudScale());
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_COLOR)->set(mLiveSky->getSunlightColor() / SLIDER_SCALE_SUN_AMBIENT);
+
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId());
+ getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID());
+
+ LLColor3 glow(mLiveSky->getGlow());
+
+ // takes 40 - 0.2 range -> 0 - 1.99 UI range
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R));
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mLiveSky->getStarBrightness());
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mLiveSky->getSunScale());
+
+ // Sun rotation
+ LLQuaternion quat = mLiveSky->getSunRotation();
+ F32 azimuth;
+ F32 elevation;
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+ getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+ // Moon rotation
+ quat = mLiveSky->getMoonRotation();
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+ getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+}
+
+
+void LLFloaterEnvironmentAdjust::captureCurrentEnvironment()
+{
+ LLEnvironment &environment(LLEnvironment::instance());
+ bool updatelocal(false);
+
+ if (environment.hasEnvironment(LLEnvironment::ENV_LOCAL))
+ {
+ if (environment.getEnvironmentDay(LLEnvironment::ENV_LOCAL))
+ { // We have a full day cycle in the local environment. Freeze the sky
+ mLiveSky = environment.getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL)->buildClone();
+ mLiveWater = environment.getEnvironmentFixedWater(LLEnvironment::ENV_LOCAL)->buildClone();
+ updatelocal = true;
+ }
+ else
+ { // otherwise we can just use the sky.
+ mLiveSky = environment.getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
+ mLiveWater = environment.getEnvironmentFixedWater(LLEnvironment::ENV_LOCAL);
+ }
+ }
+ else
+ {
+ mLiveSky = environment.getEnvironmentFixedSky(LLEnvironment::ENV_PARCEL, true)->buildClone();
+ mLiveWater = environment.getEnvironmentFixedWater(LLEnvironment::ENV_PARCEL, true)->buildClone();
+ updatelocal = true;
+ }
+
+ if (updatelocal)
+ {
+ environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveSky, FLOATER_ENVIRONMENT_UPDATE);
+ environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveWater, FLOATER_ENVIRONMENT_UPDATE);
+ }
+ environment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ environment.updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+
+}
+
+void LLFloaterEnvironmentAdjust::onButtonReset()
+{
+ LLNotificationsUtil::add("PersonalSettingsConfirmReset", LLSD(), LLSD(),
+ [this](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ this->closeFloater();
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().updateEnvironment();
+ }
+ });
+
+}
+//-------------------------------------------------------------------------
+void LLFloaterEnvironmentAdjust::onAmbientLightChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setAmbientColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->get() * SLIDER_SCALE_SUN_AMBIENT));
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onBlueHorizonChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setBlueHorizon(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onBlueDensityChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setBlueDensity(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onHazeHorizonChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setHazeHorizon(getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onHazeDensityChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setHazeDensity(getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onSceneGammaChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setGamma(getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onCloudColorChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setCloudColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->get()));
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onCloudCoverageChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setCloudShadow(getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onCloudScaleChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setCloudScale(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onGlowChanged()
+{
+ if (!mLiveSky)
+ return;
+ LLColor3 glow(getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->getValue().asReal(), 0.0f, getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->getValue().asReal());
+
+ // takes 0 - 1.99 UI range -> 40 -> 0.2 range
+ glow.mV[0] = (2.0f - glow.mV[0]) * SLIDER_SCALE_GLOW_R;
+ glow.mV[2] *= SLIDER_SCALE_GLOW_B;
+
+ mLiveSky->setGlow(glow);
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onStarBrightnessChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setStarBrightness(getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->getValue().asReal());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onSunRotationChanged()
+{
+ LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
+ F32 azimuth;
+ F32 elevation;
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+ if (mLiveSky)
+ {
+ mLiveSky->setSunRotation(quat);
+ mLiveSky->update();
+ }
+}
+
+void LLFloaterEnvironmentAdjust::onSunAzimElevChanged()
+{
+ F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
+ F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
+ LLQuaternion quat;
+
+ azimuth *= DEG_TO_RAD;
+ elevation *= DEG_TO_RAD;
+
+ if (is_approx_zero(elevation))
+ {
+ elevation = F_APPROXIMATELY_ZERO;
+ }
+
+ quat.setAngleAxis(-elevation, 0, 1, 0);
+ LLQuaternion az_quat;
+ az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+ quat *= az_quat;
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+ if (mLiveSky)
+ {
+ mLiveSky->setSunRotation(quat);
+ mLiveSky->update();
+ }
+}
+
+void LLFloaterEnvironmentAdjust::onSunScaleChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setSunScale((getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->getValue().asReal()));
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onMoonRotationChanged()
+{
+ LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
+ F32 azimuth;
+ F32 elevation;
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+ if (mLiveSky)
+ {
+ mLiveSky->setMoonRotation(quat);
+ mLiveSky->update();
+ }
+}
+
+void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged()
+{
+ F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
+ F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
+ LLQuaternion quat;
+
+ azimuth *= DEG_TO_RAD;
+ elevation *= DEG_TO_RAD;
+
+ if (is_approx_zero(elevation))
+ {
+ elevation = F_APPROXIMATELY_ZERO;
+ }
+
+ quat.setAngleAxis(-elevation, 0, 1, 0);
+ LLQuaternion az_quat;
+ az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+ quat *= az_quat;
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+
+ if (mLiveSky)
+ {
+ mLiveSky->setMoonRotation(quat);
+ mLiveSky->update();
+ }
+}
+
+void LLFloaterEnvironmentAdjust::onCloudMapChanged()
+{
+ if (!mLiveSky)
+ return;
+ mLiveSky->setCloudNoiseTextureId(getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->getValue().asUUID());
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::onWaterMapChanged()
+{
+ if (!mLiveWater)
+ return;
+ mLiveWater->setNormalMapID(getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->getValue().asUUID());
+ mLiveWater->update();
+}
+
+void LLFloaterEnvironmentAdjust::onSunColorChanged()
+{
+ if (!mLiveSky)
+ return;
+ LLColor3 color(getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_COLOR)->get());
+
+ color *= SLIDER_SCALE_SUN_AMBIENT;
+
+ mLiveSky->setSunlightColor(color);
+ mLiveSky->update();
+}
+
+
+void LLFloaterEnvironmentAdjust::onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version)
+{
+ if (env == LLEnvironment::ENV_LOCAL)
+ { // a new local environment has been applied
+ if (version != FLOATER_ENVIRONMENT_UPDATE)
+ { // not by this floater
+ captureCurrentEnvironment();
+ refresh();
+ }
+ }
+}
diff --git a/indra/newview/llfloaterenvironmentadjust.h b/indra/newview/llfloaterenvironmentadjust.h
new file mode 100644
index 0000000000..05ff011be5
--- /dev/null
+++ b/indra/newview/llfloaterenvironmentadjust.h
@@ -0,0 +1,94 @@
+/**
+ * @file llfloaterenvironmentadjust.h
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#ifndef LL_FLOATERENVIRONMENTADJUST_H
+#define LL_FLOATERENVIRONMENTADJUST_H
+
+#include "llfloater.h"
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+#include "llenvironment.h"
+
+#include "boost/signals2.hpp"
+
+class LLButton;
+class LLLineEditor;
+
+/**
+ * Floater container for taking a snapshot of the current environment and making minor adjustments.
+ */
+class LLFloaterEnvironmentAdjust : public LLFloater
+{
+ LOG_CLASS(LLFloaterEnvironmentAdjust);
+
+public:
+ LLFloaterEnvironmentAdjust(const LLSD &key);
+ virtual ~LLFloaterEnvironmentAdjust();
+
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+
+ virtual void refresh() override;
+
+private:
+ void captureCurrentEnvironment();
+
+ void onAmbientLightChanged();
+ void onBlueHorizonChanged();
+ void onBlueDensityChanged();
+ void onHazeHorizonChanged();
+ void onHazeDensityChanged();
+ void onSceneGammaChanged();
+
+ void onCloudColorChanged();
+ void onCloudCoverageChanged();
+ void onCloudScaleChanged();
+ void onSunColorChanged();
+
+ void onGlowChanged();
+ void onStarBrightnessChanged();
+ void onSunRotationChanged();
+ void onSunAzimElevChanged();
+ void onSunScaleChanged();
+
+ void onMoonRotationChanged();
+ void onMoonAzimElevChanged();
+
+ void onCloudMapChanged();
+ void onWaterMapChanged();
+
+ void onButtonReset();
+
+ void onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version);
+
+ LLSettingsSky::ptr_t mLiveSky;
+ LLSettingsWater::ptr_t mLiveWater;
+ LLEnvironment::connection_t mEventConnection;
+};
+
+#endif // LL_FLOATERFIXEDENVIRONMENT_H
diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp
deleted file mode 100644
index 4dbc8cdee0..0000000000
--- a/indra/newview/llfloaterenvironmentsettings.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * @file llfloaterenvironmentsettings.cpp
- * @brief LLFloaterEnvironmentSettings class definition
- *
- * $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$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterenvironmentsettings.h"
-
-#include "llcombobox.h"
-#include "llradiogroup.h"
-
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
-#include "llwaterparammanager.h"
-#include "llwlparamset.h"
-#include "llwlparammanager.h"
-
-LLFloaterEnvironmentSettings::LLFloaterEnvironmentSettings(const LLSD &key)
-: LLFloater(key)
- ,mRegionSettingsRadioGroup(NULL)
- ,mDayCycleSettingsRadioGroup(NULL)
- ,mWaterPresetCombo(NULL)
- ,mSkyPresetCombo(NULL)
- ,mDayCyclePresetCombo(NULL)
-{
-}
-
-// virtual
-BOOL LLFloaterEnvironmentSettings::postBuild()
-{
- mRegionSettingsRadioGroup = getChild<LLRadioGroup>("region_settings_radio_group");
- mRegionSettingsRadioGroup->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSwitchRegionSettings, this));
-
- mDayCycleSettingsRadioGroup = getChild<LLRadioGroup>("sky_dayc_settings_radio_group");
- mDayCycleSettingsRadioGroup->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSwitchDayCycle, this));
-
- mWaterPresetCombo = getChild<LLComboBox>("water_settings_preset_combo");
- mWaterPresetCombo->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSelectWaterPreset, this));
-
- mSkyPresetCombo = getChild<LLComboBox>("sky_settings_preset_combo");
- mSkyPresetCombo->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSelectSkyPreset, this));
-
- mDayCyclePresetCombo = getChild<LLComboBox>("dayc_settings_preset_combo");
- mDayCyclePresetCombo->setCommitCallback(boost::bind(&LLFloaterEnvironmentSettings::onSelectDayCyclePreset, this));
-
- childSetCommitCallback("ok_btn", boost::bind(&LLFloaterEnvironmentSettings::onBtnOK, this), NULL);
- getChild<LLUICtrl>("ok_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpUserPrefs, LLEnvManagerNew::getInstance()));
- childSetCommitCallback("cancel_btn", boost::bind(&LLFloaterEnvironmentSettings::onBtnCancel, this), NULL);
- getChild<LLUICtrl>("cancel_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpPresets, LLEnvManagerNew::getInstance()));
-
- setCloseCallback(boost::bind(&LLFloaterEnvironmentSettings::cancel, this));
-
- LLEnvManagerNew::instance().setPreferencesChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::refresh, this));
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLFloaterEnvironmentSettings::populateDayCyclePresetsList, this));
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateSkyPresetsList, this));
- LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterEnvironmentSettings::populateWaterPresetsList, this));
-
- return TRUE;
-}
-
-// virtual
-void LLFloaterEnvironmentSettings::onOpen(const LLSD& key)
-{
- refresh();
-}
-
-void LLFloaterEnvironmentSettings::onSwitchRegionSettings()
-{
- getChild<LLView>("user_environment_settings")->setEnabled(mRegionSettingsRadioGroup->getSelectedIndex() != 0);
-
- apply();
-}
-
-void LLFloaterEnvironmentSettings::onSwitchDayCycle()
-{
- bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
-
- mSkyPresetCombo->setEnabled(is_fixed_sky);
- mDayCyclePresetCombo->setEnabled(!is_fixed_sky);
-
- apply();
-}
-
-void LLFloaterEnvironmentSettings::onSelectWaterPreset()
-{
- apply();
-}
-
-void LLFloaterEnvironmentSettings::onSelectSkyPreset()
-{
- apply();
-}
-
-void LLFloaterEnvironmentSettings::onSelectDayCyclePreset()
-{
- apply();
-}
-
-void LLFloaterEnvironmentSettings::onBtnOK()
-{
- // Save and apply new user preferences.
- bool use_region_settings = mRegionSettingsRadioGroup->getSelectedIndex() == 0;
- bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
- std::string water_preset = mWaterPresetCombo->getValue().asString();
- std::string sky_preset = mSkyPresetCombo->getValue().asString();
- std::string day_cycle = mDayCyclePresetCombo->getValue().asString();
-
- LLEnvManagerNew::instance().setUserPrefs(
- water_preset,
- sky_preset,
- day_cycle,
- use_fixed_sky,
- use_region_settings);
-
- // *TODO: This triggers applying user preferences again, which is suboptimal.
- closeFloater();
-}
-
-void LLFloaterEnvironmentSettings::onBtnCancel()
-{
- closeFloater();
-}
-
-void LLFloaterEnvironmentSettings::refresh()
-{
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
-
- bool use_region_settings = env_mgr.getUseRegionSettings();
- bool use_fixed_sky = env_mgr.getUseFixedSky();
-
- // Set up radio buttons according to user preferences.
- mRegionSettingsRadioGroup->setSelectedIndex(use_region_settings ? 0 : 1);
- mDayCycleSettingsRadioGroup->setSelectedIndex(use_fixed_sky ? 0 : 1);
-
- // Populate the combo boxes with appropriate lists of available presets.
- populateWaterPresetsList();
- populateSkyPresetsList();
- populateDayCyclePresetsList();
-
- // Enable/disable other controls based on user preferences.
- getChild<LLView>("user_environment_settings")->setEnabled(!use_region_settings);
- mSkyPresetCombo->setEnabled(use_fixed_sky);
- mDayCyclePresetCombo->setEnabled(!use_fixed_sky);
-
- // Select the current presets in combo boxes.
- mWaterPresetCombo->selectByValue(env_mgr.getWaterPresetName());
- mSkyPresetCombo->selectByValue(env_mgr.getSkyPresetName());
- mDayCyclePresetCombo->selectByValue(env_mgr.getDayCycleName());
-}
-
-void LLFloaterEnvironmentSettings::apply()
-{
- // Update environment with the user choice.
- bool use_region_settings = mRegionSettingsRadioGroup->getSelectedIndex() == 0;
- bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
- std::string water_preset = mWaterPresetCombo->getValue().asString();
- std::string sky_preset = mSkyPresetCombo->getValue().asString();
- std::string day_cycle = mDayCyclePresetCombo->getValue().asString();
-
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- if (use_region_settings)
- {
- env_mgr.useRegionSettings();
- }
- else
- {
- if (use_fixed_sky)
- {
- env_mgr.useSkyPreset(sky_preset);
- }
- else
- {
- env_mgr.useDayCycle(day_cycle, LLEnvKey::SCOPE_LOCAL);
- }
-
- env_mgr.useWaterPreset(water_preset);
- }
-}
-
-void LLFloaterEnvironmentSettings::cancel()
-{
- // Revert environment to user preferences.
- LLEnvManagerNew::instance().usePrefs();
-}
-
-void LLFloaterEnvironmentSettings::populateWaterPresetsList()
-{
- mWaterPresetCombo->removeall();
-
- std::list<std::string> user_presets, system_presets;
- LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);
-
- // Add user presets first.
- for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mWaterPresetCombo->add(*it);
- }
-
- if (user_presets.size() > 0)
- {
- mWaterPresetCombo->addSeparator();
- }
-
- // Add system presets.
- for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it)
- {
- mWaterPresetCombo->add(*it);
- }
-}
-
-void LLFloaterEnvironmentSettings::populateSkyPresetsList()
-{
- mSkyPresetCombo->removeall();
-
- LLWLParamManager::preset_name_list_t region_presets; // unused as we don't list region presets here
- LLWLParamManager::preset_name_list_t user_presets, sys_presets;
- LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
-
- // Add user presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it);
- }
-
- if (!user_presets.empty())
- {
- mSkyPresetCombo->addSeparator();
- }
-
- // Add system presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it);
- }
-}
-
-void LLFloaterEnvironmentSettings::populateDayCyclePresetsList()
-{
- mDayCyclePresetCombo->removeall();
-
- LLDayCycleManager::preset_name_list_t user_days, sys_days;
- LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
-
- // Add user days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- mDayCyclePresetCombo->add(*it);
- }
-
- if (user_days.size() > 0)
- {
- mDayCyclePresetCombo->addSeparator();
- }
-
- // Add system days.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
- {
- mDayCyclePresetCombo->add(*it);
- }
-}
diff --git a/indra/newview/llfloaterenvironmentsettings.h b/indra/newview/llfloaterenvironmentsettings.h
deleted file mode 100644
index 0ab458a0f6..0000000000
--- a/indra/newview/llfloaterenvironmentsettings.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @file llfloaterenvironmentsettings.h
- * @brief LLFloaterEnvironmentSettings class definition
- *
- * $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$
- */
-
-#ifndef LL_LLFLOATERENVIRONMENTSETTINGS_H
-#define LL_LLFLOATERENVIRONMENTSETTINGS_H
-
-#include "llfloater.h"
-
-class LLComboBox;
-class LLRadioGroup;
-
-class LLFloaterEnvironmentSettings : public LLFloater
-{
- LOG_CLASS(LLFloaterEnvironmentSettings);
-
-public:
- LLFloaterEnvironmentSettings(const LLSD &key);
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
-
-private:
- void onSwitchRegionSettings();
- void onSwitchDayCycle();
-
- void onSelectWaterPreset();
- void onSelectSkyPreset();
- void onSelectDayCyclePreset();
-
- void onBtnOK();
- void onBtnCancel();
-
- void refresh(); /// update controls with user prefs
- void apply();
- void cancel();
-
- void populateWaterPresetsList();
- void populateSkyPresetsList();
- void populateDayCyclePresetsList();
-
- LLRadioGroup* mRegionSettingsRadioGroup;
- LLRadioGroup* mDayCycleSettingsRadioGroup;
-
- LLComboBox* mWaterPresetCombo;
- LLComboBox* mSkyPresetCombo;
- LLComboBox* mDayCyclePresetCombo;
-};
-
-#endif // LL_LLFLOATERENVIRONMENTSETTINGS_H
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index 3e303e0932..a6640cc073 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -110,7 +110,7 @@ void LLFloaterEvent::setEventID(const U32 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;
+ url << gSavedSettings.getString("EventURL") << event_id << std::endl;
// and load the URL in the web view
mBrowser->navigateTo(url.str());
diff --git a/indra/newview/llfloaterexperiencepicker.cpp b/indra/newview/llfloaterexperiencepicker.cpp
index bb54c57baf..c642da7b83 100644
--- a/indra/newview/llfloaterexperiencepicker.cpp
+++ b/indra/newview/llfloaterexperiencepicker.cpp
@@ -74,59 +74,8 @@ LLFloaterExperiencePicker* LLFloaterExperiencePicker::show( select_callback_t ca
void LLFloaterExperiencePicker::drawFrustum()
{
- if(mFrustumOrigin.get())
- {
- LLView * frustumOrigin = mFrustumOrigin.get();
- LLRect origin_rect;
- frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
- // draw context cone connecting color picker with color swatch in parent floater
- LLRect local_rect = getLocalRect();
- if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::QUADS);
- {
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
-
- gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
- gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
- gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
- }
- gGL.end();
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
- }
- }
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
}
void LLFloaterExperiencePicker::draw()
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
new file mode 100644
index 0000000000..4f2c36f45b
--- /dev/null
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -0,0 +1,554 @@
+/**
+ * @file llfloaterfixedenvironment.cpp
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterfixedenvironment.h"
+
+#include <boost/make_shared.hpp>
+
+// libs
+#include "llbutton.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llsliderctrl.h"
+#include "lltabcontainer.h"
+#include "llfilepicker.h"
+#include "lllocalbitmaps.h"
+#include "llsettingspicker.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
+#include "llviewerparcelmgr.h"
+
+// newview
+#include "llpaneleditwater.h"
+#include "llpaneleditsky.h"
+
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+#include "llenvironment.h"
+#include "llagent.h"
+#include "llparcel.h"
+#include "lltrans.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+
+extern LLControlGroup gSavedSettings;
+
+namespace
+{
+ const std::string FIELD_SETTINGS_NAME("settings_name");
+
+ const std::string CONTROL_TAB_AREA("tab_settings");
+
+ const std::string BUTTON_NAME_IMPORT("btn_import");
+ const std::string BUTTON_NAME_COMMIT("btn_commit");
+ const std::string BUTTON_NAME_CANCEL("btn_cancel");
+ const std::string BUTTON_NAME_FLYOUT("btn_flyout");
+ const std::string BUTTON_NAME_LOAD("btn_load");
+
+ const std::string ACTION_SAVE("save_settings");
+ const std::string ACTION_SAVEAS("save_as_new_settings");
+ const std::string ACTION_COMMIT("commit_changes");
+ const std::string ACTION_APPLY_LOCAL("apply_local");
+ const std::string ACTION_APPLY_PARCEL("apply_parcel");
+ const std::string ACTION_APPLY_REGION("apply_region");
+
+ const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
+}
+
+
+//=========================================================================
+LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) :
+ LLFloaterEditEnvironmentBase(key),
+ mFlyoutControl(nullptr)
+{
+}
+
+LLFloaterFixedEnvironment::~LLFloaterFixedEnvironment()
+{
+ delete mFlyoutControl;
+}
+
+BOOL LLFloaterFixedEnvironment::postBuild()
+{
+ mTab = getChild<LLTabContainer>(CONTROL_TAB_AREA);
+ mTxtName = getChild<LLLineEditor>(FIELD_SETTINGS_NAME);
+
+ mTxtName->setCommitOnFocusLost(TRUE);
+ mTxtName->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNameChanged(mTxtName->getValue().asString()); });
+
+ getChild<LLButton>(BUTTON_NAME_IMPORT)->setClickedCallback([this](LLUICtrl *, const LLSD &) { onButtonImport(); });
+ getChild<LLButton>(BUTTON_NAME_CANCEL)->setClickedCallback([this](LLUICtrl *, const LLSD &) { onClickCloseBtn(); });
+ getChild<LLButton>(BUTTON_NAME_LOAD)->setClickedCallback([this](LLUICtrl *, const LLSD &) { onButtonLoad(); });
+
+ mFlyoutControl = new LLFlyoutComboBtnCtrl(this, BUTTON_NAME_COMMIT, BUTTON_NAME_FLYOUT, XML_FLYOUTMENU_FILE, false);
+ mFlyoutControl->setAction([this](LLUICtrl *ctrl, const LLSD &data) { onButtonApply(ctrl, data); });
+ mFlyoutControl->setMenuItemVisible(ACTION_COMMIT, false);
+
+ return TRUE;
+}
+
+void LLFloaterFixedEnvironment::onOpen(const LLSD& key)
+{
+ LLUUID invid;
+
+ if (key.has(KEY_INVENTORY_ID))
+ {
+ invid = key[KEY_INVENTORY_ID].asUUID();
+ }
+
+ loadInventoryItem(invid);
+ LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+
+ updateEditEnvironment();
+ syncronizeTabs();
+ refresh();
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+
+}
+
+void LLFloaterFixedEnvironment::onClose(bool app_quitting)
+{
+ doCloseInventoryFloater(app_quitting);
+
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+
+ mSettings.reset();
+ syncronizeTabs();
+}
+
+void LLFloaterFixedEnvironment::refresh()
+{
+ if (!mSettings)
+ {
+ // disable everything.
+ return;
+ }
+
+ bool is_inventory_avail = canUseInventory();
+
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVE, is_inventory_avail && mCanMod && !mInventoryId.isNull());
+ mFlyoutControl->setMenuItemEnabled(ACTION_SAVEAS, is_inventory_avail && mCanCopy);
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_PARCEL, canApplyParcel());
+ mFlyoutControl->setMenuItemEnabled(ACTION_APPLY_REGION, canApplyRegion());
+
+ mTxtName->setValue(mSettings->getName());
+ mTxtName->setEnabled(mCanMod);
+
+ S32 count = mTab->getTabCount();
+
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(mTab->getPanelByIndex(idx));
+ if (panel)
+ {
+ panel->setCanChangeSettings(mCanMod);
+ panel->refresh();
+ }
+ }
+}
+
+void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+ mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ?
+ updateEditEnvironment();
+ syncronizeTabs();
+ refresh();
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
+void LLFloaterFixedEnvironment::syncronizeTabs()
+{
+ S32 count = mTab->getTabCount();
+
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(mTab->getPanelByIndex(idx));
+ if (panel)
+ panel->setSettings(mSettings);
+ }
+}
+
+LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker()
+{
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
+
+ // Show the dialog
+ if (!picker)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null);
+
+ mInventoryFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID() /*data["Track"]*/); });
+ }
+
+ return picker;
+}
+
+void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id)
+{
+ loadInventoryItem(item_id);
+}
+
+void LLFloaterFixedEnvironment::onNameChanged(const std::string &name)
+{
+ mSettings->setName(name);
+ setDirtyFlag();
+}
+
+void LLFloaterFixedEnvironment::onButtonImport()
+{
+ checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); });
+}
+
+void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
+{
+ std::string ctrl_action = ctrl->getName();
+
+ std::string local_desc;
+ LLSettingsBase::ptr_t setting_clone;
+ bool is_local = false; // because getString can be empty
+ if (mSettings->getSettingsType() == "water")
+ {
+ LLSettingsWater::ptr_t water = std::static_pointer_cast<LLSettingsWater>(mSettings);
+ if (water)
+ {
+ setting_clone = water->buildClone();
+ // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr
+ if (LLLocalBitmapMgr::getInstance()->isLocal(water->getNormalMapID()))
+ {
+ local_desc = LLTrans::getString("EnvironmentNormalMap");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(water->getTransparentTextureID()))
+ {
+ local_desc = LLTrans::getString("EnvironmentTransparent");
+ is_local = true;
+ }
+ }
+ }
+ else if (mSettings->getSettingsType() == "sky")
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(mSettings);
+ if (sky)
+ {
+ setting_clone = sky->buildClone();
+ if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getSunTextureId()))
+ {
+ local_desc = LLTrans::getString("EnvironmentSun");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getMoonTextureId()))
+ {
+ local_desc = LLTrans::getString("EnvironmentMoon");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getCloudNoiseTextureId()))
+ {
+ local_desc = LLTrans::getString("EnvironmentCloudNoise");
+ is_local = true;
+ }
+ else if (LLLocalBitmapMgr::getInstance()->isLocal(sky->getBloomTextureId()))
+ {
+ local_desc = LLTrans::getString("EnvironmentBloom");
+ is_local = true;
+ }
+ }
+ }
+
+ if (is_local)
+ {
+ LLSD args;
+ args["FIELD"] = local_desc;
+ LLNotificationsUtil::add("WLLocalTextureFixedBlock", args);
+ return;
+ }
+
+ if (ctrl_action == ACTION_SAVE)
+ {
+ doApplyUpdateInventory(setting_clone);
+ }
+ else if (ctrl_action == ACTION_SAVEAS)
+ {
+ LLSD args;
+ args["DESC"] = mSettings->getName();
+ LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterFixedEnvironment::onSaveAsCommit, this, _1, _2, setting_clone));
+ }
+ else if ((ctrl_action == ACTION_APPLY_LOCAL) ||
+ (ctrl_action == ACTION_APPLY_PARCEL) ||
+ (ctrl_action == ACTION_APPLY_REGION))
+ {
+ doApplyEnvironment(ctrl_action, setting_clone);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Unknown settings action '" << ctrl_action << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
+ else
+ closeFloater();
+}
+
+void LLFloaterFixedEnvironment::onButtonLoad()
+{
+ checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); });
+}
+
+void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ if (inventory_id.isNull() || !results["success"].asBoolean())
+ {
+ LLNotificationsUtil::add("CantCreateInventory");
+ return;
+ }
+ onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
+ bool can_trans = true;
+ if (mInventoryItem)
+ {
+ LLPermissions perms = mInventoryItem->getPermissions();
+
+ LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+ if (created_item)
+ {
+ can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+ created_item->setPermissions(perms);
+ created_item->updateServer(false);
+ }
+ }
+ clearDirtyFlag();
+ setFocus(TRUE); // Call back the focus...
+ loadInventoryItem(inventory_id, can_trans);
+}
+
+void LLFloaterFixedEnvironment::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+ LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+ clearDirtyFlag();
+ if (inventory_id != mInventoryId)
+ {
+ loadInventoryItem(inventory_id);
+ }
+}
+
+
+void LLFloaterFixedEnvironment::clearDirtyFlag()
+{
+ mIsDirty = false;
+
+ S32 count = mTab->getTabCount();
+
+ for (S32 idx = 0; idx < count; ++idx)
+ {
+ LLSettingsEditPanel *panel = static_cast<LLSettingsEditPanel *>(mTab->getPanelByIndex(idx));
+ if (panel)
+ panel->clearIsDirty();
+ }
+
+}
+
+void LLFloaterFixedEnvironment::doSelectFromInventory()
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+
+ picker->setSettingsFilter(mSettings->getSettingsTypeValue());
+ picker->openFloater();
+ picker->setFocus(TRUE);
+}
+
+//=========================================================================
+LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key):
+ LLFloaterFixedEnvironment(key)
+{}
+
+BOOL LLFloaterFixedEnvironmentWater::postBuild()
+{
+ if (!LLFloaterFixedEnvironment::postBuild())
+ return FALSE;
+
+ LLPanelSettingsWater * panel;
+ panel = new LLPanelSettingsWaterMainTab;
+ panel->buildFromFile("panel_settings_water.xml");
+ panel->setWater(std::static_pointer_cast<LLSettingsWater>(mSettings));
+ panel->setOnDirtyFlagChanged( [this] (LLPanel *, bool value) { onPanelDirtyFlagChanged(value); });
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
+
+ return TRUE;
+}
+
+void LLFloaterFixedEnvironmentWater::updateEditEnvironment(void)
+{
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT,
+ std::static_pointer_cast<LLSettingsWater>(mSettings));
+}
+
+void LLFloaterFixedEnvironmentWater::onOpen(const LLSD& key)
+{
+ if (!mSettings)
+ {
+ // Initialize the settings, take a snapshot of the current water.
+ mSettings = LLEnvironment::instance().getEnvironmentFixedWater(LLEnvironment::ENV_CURRENT)->buildClone();
+ mSettings->setName("Snapshot water (new)");
+
+ // TODO: Should we grab sky and keep it around for reference?
+ }
+
+ LLFloaterFixedEnvironment::onOpen(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();
+}
+
+void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<std::string>& filenames)
+{
+ LLSD messages;
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LL_DEBUGS("ENVEDIT") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsWater::ptr_t legacywater = LLEnvironment::createWaterFromLegacyPreset(filename, messages);
+
+ if (!legacywater)
+ {
+ LLNotificationsUtil::add("WLImportFail", messages);
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ setDirtyFlag();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater);
+ setEditSettings(legacywater);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
+}
+
+//=========================================================================
+LLFloaterFixedEnvironmentSky::LLFloaterFixedEnvironmentSky(const LLSD &key) :
+ LLFloaterFixedEnvironment(key)
+{}
+
+BOOL LLFloaterFixedEnvironmentSky::postBuild()
+{
+ if (!LLFloaterFixedEnvironment::postBuild())
+ return FALSE;
+
+ LLPanelSettingsSky * panel;
+ panel = new LLPanelSettingsSkyAtmosTab;
+ panel->buildFromFile("panel_settings_sky_atmos.xml");
+ panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings));
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); });
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true));
+
+ panel = new LLPanelSettingsSkyCloudTab;
+ panel->buildFromFile("panel_settings_sky_clouds.xml");
+ panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings));
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); });
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false));
+
+ panel = new LLPanelSettingsSkySunMoonTab;
+ panel->buildFromFile("panel_settings_sky_sunmoon.xml");
+ panel->setSky(std::static_pointer_cast<LLSettingsSky>(mSettings));
+ panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); });
+ mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false));
+
+ return TRUE;
+}
+
+void LLFloaterFixedEnvironmentSky::updateEditEnvironment(void)
+{
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT,
+ std::static_pointer_cast<LLSettingsSky>(mSettings));
+}
+
+void LLFloaterFixedEnvironmentSky::onOpen(const LLSD& key)
+{
+ if (!mSettings)
+ {
+ // Initialize the settings, take a snapshot of the current water.
+ mSettings = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_CURRENT)->buildClone();
+ mSettings->setName("Snapshot sky (new)");
+ LLEnvironment::instance().saveBeaconsState();
+ // TODO: Should we grab water and keep it around for reference?
+ }
+
+ LLFloaterFixedEnvironment::onOpen(key);
+}
+
+void LLFloaterFixedEnvironmentSky::onClose(bool app_quitting)
+{
+ LLEnvironment::instance().revertBeaconsState();
+
+ LLFloaterFixedEnvironment::onClose(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();
+}
+
+void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std::string>& filenames)
+{
+ if (filenames.size() < 1) return;
+ std::string filename = filenames[0];
+ LLSD messages;
+
+ LL_DEBUGS("ENVEDIT") << "Selected file: " << filename << LL_ENDL;
+ LLSettingsSky::ptr_t legacysky = LLEnvironment::createSkyFromLegacyPreset(filename, messages);
+
+ if (!legacysky)
+ {
+ LLNotificationsUtil::add("WLImportFail", messages);
+
+ return;
+ }
+
+ loadInventoryItem(LLUUID::null);
+
+ setDirtyFlag();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky);
+ setEditSettings(legacysky);
+ LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
+}
+
+//=========================================================================
diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h
new file mode 100644
index 0000000000..f35f4a4368
--- /dev/null
+++ b/indra/newview/llfloaterfixedenvironment.h
@@ -0,0 +1,138 @@
+/**
+ * @file llfloaterfixedenvironment.h
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $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$
+ */
+
+#ifndef LL_FLOATERFIXEDENVIRONMENT_H
+#define LL_FLOATERFIXEDENVIRONMENT_H
+
+#include "llfloatereditenvironmentbase.h"
+#include "llsettingsbase.h"
+#include "llflyoutcombobtn.h"
+#include "llinventory.h"
+
+#include "boost/signals2.hpp"
+
+class LLTabContainer;
+class LLButton;
+class LLLineEditor;
+class LLFloaterSettingsPicker;
+class LLFixedSettingCopiedCallback;
+
+/**
+ * Floater container for creating and editing fixed environment settings.
+ */
+class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase
+{
+ LOG_CLASS(LLFloaterFixedEnvironment);
+public:
+ LLFloaterFixedEnvironment(const LLSD &key);
+ ~LLFloaterFixedEnvironment();
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+
+ void setEditSettings(const LLSettingsBase::ptr_t &settings) { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); }
+ virtual LLSettingsBase::ptr_t getEditSettings() const override { return mSettings; }
+
+protected:
+ typedef std::function<void()> on_confirm_fn;
+
+ virtual void refresh() override;
+ void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
+ virtual void syncronizeTabs();
+
+ virtual LLFloaterSettingsPicker *getSettingsPicker() override;
+
+ LLTabContainer * mTab;
+ LLLineEditor * mTxtName;
+
+ LLSettingsBase::ptr_t mSettings;
+
+ LLFlyoutComboBtnCtrl * mFlyoutControl;
+
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+ void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+ void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+ virtual void clearDirtyFlag() override;
+ void updatePermissionFlags();
+
+ void doSelectFromInventory();
+
+ virtual void onClickCloseBtn(bool app_quitting = false) override;
+
+private:
+ void onNameChanged(const std::string &name);
+
+ void onButtonImport();
+ void onButtonApply(LLUICtrl *ctrl, const LLSD &data);
+ void onButtonLoad();
+
+ void onPickerCommitSetting(LLUUID item_id);
+};
+
+class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment
+{
+ LOG_CLASS(LLFloaterFixedEnvironmentWater);
+
+public:
+ LLFloaterFixedEnvironmentWater(const LLSD &key);
+
+ BOOL postBuild() override;
+
+ virtual void onOpen(const LLSD& key) override;
+
+protected:
+ virtual void updateEditEnvironment() override;
+
+ virtual void doImportFromDisk() override;
+ void loadWaterSettingFromFile(const std::vector<std::string>& filenames);
+
+private:
+};
+
+class LLFloaterFixedEnvironmentSky : public LLFloaterFixedEnvironment
+{
+ LOG_CLASS(LLFloaterFixedEnvironmentSky);
+
+public:
+ LLFloaterFixedEnvironmentSky(const LLSD &key);
+
+ BOOL postBuild() override;
+
+ virtual void onOpen(const LLSD& key) override;
+ virtual void onClose(bool app_quitting) override;
+
+protected:
+ virtual void updateEditEnvironment() override;
+
+ virtual void doImportFromDisk() override;
+ void loadSkySettingFromFile(const std::vector<std::string>& filenames);
+
+private:
+};
+
+#endif // LL_FLOATERFIXEDENVIRONMENT_H
diff --git a/indra/newview/llfloaterforgetuser.cpp b/indra/newview/llfloaterforgetuser.cpp
new file mode 100644
index 0000000000..97b022699f
--- /dev/null
+++ b/indra/newview/llfloaterforgetuser.cpp
@@ -0,0 +1,348 @@
+/**
+ * @file llfloaterforgetuser.cpp
+ * @brief LLFloaterForgetUser class definition.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterforgetuser.h"
+
+#include "llappviewer.h"
+#include "llcheckboxctrl.h"
+#include "llfavoritesbar.h"
+#include "llnotificationsutil.h"
+#include "llpanellogin.h" // for helper function getUserName() and to repopulate list if nessesary
+#include "llscrolllistctrl.h"
+#include "llsecapi.h"
+#include "llstartup.h"
+#include "llviewercontrol.h"
+#include "llviewernetwork.h"
+
+
+LLFloaterForgetUser::LLFloaterForgetUser(const LLSD &key)
+ : LLFloater("floater_forget_user"),
+ mLoginPanelDirty(false)
+{
+
+}
+
+LLFloaterForgetUser::~LLFloaterForgetUser()
+{
+ if (mLoginPanelDirty)
+ {
+ LLPanelLogin::resetFields();
+ }
+}
+
+BOOL LLFloaterForgetUser::postBuild()
+{
+ mScrollList = getChild<LLScrollListCtrl>("user_list");
+
+
+ bool show_grid_marks = gSavedSettings.getBOOL("ForceShowGrid");
+ show_grid_marks |= !LLGridManager::getInstance()->isInProductionGrid();
+
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+
+ if (!show_grid_marks)
+ {
+ // Figure out if there are records for more than one grid in storage
+ for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
+ grid_iter != known_grids.end();
+ grid_iter++)
+ {
+ if (!grid_iter->first.empty()
+ && grid_iter->first != MAINGRID) // a workaround since 'mIsInProductionGrid' might not be set
+ {
+ if (!gSecAPIHandler->emptyCredentialMap("login_list", grid_iter->first))
+ {
+ show_grid_marks = true;
+ break;
+ }
+
+ // "Legacy" viewer support
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid_iter->first);
+ if (cred.notNull())
+ {
+ const LLSD &ident = cred->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ show_grid_marks = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ mUserGridsCount.clear();
+ if (!show_grid_marks)
+ {
+ // just load maingrid
+ loadGridToList(MAINGRID, false);
+ }
+ else
+ {
+ for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
+ grid_iter != known_grids.end();
+ grid_iter++)
+ {
+ if (!grid_iter->first.empty())
+ {
+ loadGridToList(grid_iter->first, true);
+ }
+ }
+ }
+
+ mScrollList->selectFirstItem();
+ bool enable_button = mScrollList->getFirstSelectedIndex() != -1;
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ chk_box->setEnabled(enable_button);
+ chk_box->set(FALSE);
+ LLButton *button = getChild<LLButton>("forget");
+ button->setEnabled(enable_button);
+ button->setCommitCallback(boost::bind(&LLFloaterForgetUser::onForgetClicked, this));
+
+ return TRUE;
+}
+
+void LLFloaterForgetUser::onForgetClicked()
+{
+ LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
+ LLSD user_data = scroll_list->getSelectedValue();
+ const std::string user_id = user_data["user_id"];
+
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ BOOL delete_data = chk_box->getValue();
+
+ if (delete_data && mUserGridsCount[user_id] > 1)
+ {
+ // more than 1 grid uses this id
+ LLNotificationsUtil::add("LoginRemoveMultiGridUserData", LLSD(), LLSD(), boost::bind(&LLFloaterForgetUser::onConfirmForget, this, _1, _2));
+ return;
+ }
+
+ processForgetUser();
+}
+
+bool LLFloaterForgetUser::onConfirmForget(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ processForgetUser();
+ }
+ return false;
+}
+
+// static
+bool LLFloaterForgetUser::onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &fav_id, const std::string &grid)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ // Remove creds
+ gSecAPIHandler->removeFromCredentialMap("login_list", grid, LLStartUp::getUserId());
+
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull() && cred->userID() == LLStartUp::getUserId())
+ {
+ gSecAPIHandler->deleteCredential(cred);
+ }
+
+ // Clean favorites
+ LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
+
+ // mark data for removal
+ LLAppViewer::instance()->purgeUserDataOnExit();
+ LLAppViewer::instance()->requestQuit();
+ }
+ return false;
+}
+
+void LLFloaterForgetUser::processForgetUser()
+{
+ LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ BOOL delete_data = chk_box->getValue();
+ LLSD user_data = scroll_list->getSelectedValue();
+ const std::string user_id = user_data["user_id"];
+ const std::string grid = user_data["grid"];
+ const std::string user_name = user_data["label"]; // for favorites
+
+ if (delete_data && user_id == LLStartUp::getUserId() && LLStartUp::getStartupState() > STATE_LOGIN_WAIT)
+ {
+ // we can't delete data for user that is currently logged in
+ // we need to pass grid because we are deleting data universal to grids, but specific grid's user
+ LLNotificationsUtil::add("LoginCantRemoveCurUsername", LLSD(), LLSD(), boost::bind(onConfirmLogout, _1, _2, user_name, grid));
+ return;
+ }
+
+ // key is used for name of user's folder and in credencials
+ // user_name is edentical to favorite's username
+ forgetUser(user_id, user_name, grid, delete_data);
+ mLoginPanelDirty = true;
+ if (delete_data)
+ {
+ mUserGridsCount[user_id] = 0; //no data left to care about
+ }
+ else
+ {
+ mUserGridsCount[user_id]--;
+ }
+
+ // Update UI
+ scroll_list->deleteSelectedItems();
+ scroll_list->selectFirstItem();
+ if (scroll_list->getFirstSelectedIndex() == -1)
+ {
+ LLButton *button = getChild<LLButton>("forget");
+ button->setEnabled(false);
+ chk_box->setEnabled(false);
+ }
+}
+
+//static
+void LLFloaterForgetUser::forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data)
+{
+ // Remove creds
+ gSecAPIHandler->removeFromCredentialMap("login_list", grid, userid);
+
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull() && cred->userID() == userid)
+ {
+ gSecAPIHandler->deleteCredential(cred);
+ }
+
+ // Clean data
+ if (delete_data)
+ {
+ std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + userid;
+ gDirUtilp->deleteDirAndContents(user_path);
+
+ // Clean favorites
+ LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
+
+ // Note: we do not clean user-related files from cache because there are id dependent (inventory)
+ // files and cache has separate cleaning mechanism either way.
+ // Also this only cleans user from current grid, not all of them.
+ }
+}
+
+void LLFloaterForgetUser::loadGridToList(const std::string &grid, bool show_grid_name)
+{
+ std::string grid_label;
+ if (show_grid_name)
+ {
+ grid_label = LLGridManager::getInstance()->getGridId(grid); //login id (shortened label)
+ }
+ if (gSecAPIHandler->hasCredentialMap("login_list", grid))
+ {
+ LLSecAPIHandler::credential_map_t credencials;
+ gSecAPIHandler->loadCredentialMap("login_list", grid, credencials);
+
+ LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
+ LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
+ while (cr_iter != cr_end)
+ {
+ if (cr_iter->second.notNull()) // basic safety
+ {
+ std::string user_label = LLPanelLogin::getUserName(cr_iter->second);
+ LLSD user_data;
+ user_data["user_id"] = cr_iter->first;
+ user_data["label"] = user_label;
+ user_data["grid"] = grid;
+
+ if (show_grid_name)
+ {
+ user_label += " (" + grid_label + ")";
+ }
+
+ LLScrollListItem::Params item_params;
+ item_params.value(user_data);
+ item_params.columns.add()
+ .value(user_label)
+ .column("user")
+ .font(LLFontGL::getFontSansSerifSmall());
+ mScrollList->addRow(item_params, ADD_BOTTOM);
+
+ // Add one to grid count
+ std::map<std::string, S32>::iterator found = mUserGridsCount.find(cr_iter->first);
+ if (found != mUserGridsCount.end())
+ {
+ found->second++;
+ }
+ else
+ {
+ mUserGridsCount[cr_iter->first] = 1;
+ }
+ }
+ cr_iter++;
+ }
+ }
+ else
+ {
+ // "Legacy" viewer support
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull())
+ {
+ const LLSD &ident = cred->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ std::string user_label = LLPanelLogin::getUserName(cred);
+ LLSD user_data;
+ user_data["user_id"] = cred->userID();
+ user_data["label"] = user_label;
+ user_data["grid"] = grid;
+
+ if (show_grid_name)
+ {
+ user_label += " (" + grid_label + ")";
+ }
+
+ LLScrollListItem::Params item_params;
+ item_params.value(user_data);
+ item_params.columns.add()
+ .value(user_label)
+ .column("user")
+ .font(LLFontGL::getFontSansSerifSmall());
+ mScrollList->addRow(item_params, ADD_BOTTOM);
+
+ // Add one to grid count
+ std::map<std::string, S32>::iterator found = mUserGridsCount.find(cred->userID());
+ if (found != mUserGridsCount.end())
+ {
+ found->second++;
+ }
+ else
+ {
+ mUserGridsCount[cred->userID()] = 1;
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/indra/newview/llfloaterforgetuser.h b/indra/newview/llfloaterforgetuser.h
new file mode 100644
index 0000000000..801fcbb412
--- /dev/null
+++ b/indra/newview/llfloaterforgetuser.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterforgetuser.h
+ * @brief LLFloaterForgetUser class declaration.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#ifndef LL_LLFLOATERFORGETUSER_H
+#define LL_LLFLOATERFORGETUSER_H
+
+#include "llfloater.h"
+
+class LLScrollListCtrl;
+
+class LLFloaterForgetUser : public LLFloater
+{
+public:
+ LLFloaterForgetUser(const LLSD &key);
+ ~LLFloaterForgetUser();
+
+ BOOL postBuild();
+ void onForgetClicked();
+
+private:
+ bool onConfirmForget(const LLSD& notification, const LLSD& response);
+ static bool onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &favorites_id, const std::string &grid);
+ void processForgetUser();
+ static void forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data);
+ void loadGridToList(const std::string &grid, bool show_grid_name);
+
+ LLScrollListCtrl *mScrollList;
+
+ bool mLoginPanelDirty;
+ std::map<std::string, S32> mUserGridsCount;
+};
+
+#endif
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index e778e8eb9e..c4e0dd483f 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -485,7 +485,7 @@ void LLFloaterGesture::onClickNew()
"",
LLAssetType::AT_GESTURE,
LLInventoryType::IT_GESTURE,
- NOT_WEARABLE,
+ NO_INV_SUBTYPE,
PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Gestures"),
cb);
}
diff --git a/indra/newview/llfloatergroupinvite.cpp b/indra/newview/llfloatergroupinvite.cpp
index 7fdba8734a..30c90ac184 100644
--- a/indra/newview/llfloatergroupinvite.cpp
+++ b/indra/newview/llfloatergroupinvite.cpp
@@ -108,7 +108,7 @@ LLFloaterGroupInvite::~LLFloaterGroupInvite()
}
// static
-void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids)
+void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids, bool request_update)
{
const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
S32 floater_header_size = floater_params.header_height;
@@ -126,9 +126,12 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agen
group_id,
(LLFloaterGroupInvite*)NULL);
- // refresh group information
- gAgent.sendAgentDataUpdateRequest();
- LLGroupMgr::getInstance()->clearGroupData(group_id);
+ if (request_update)
+ {
+ // refresh group information
+ gAgent.sendAgentDataUpdateRequest();
+ LLGroupMgr::getInstance()->clearGroupData(group_id);
+ }
if (!fgi)
diff --git a/indra/newview/llfloatergroupinvite.h b/indra/newview/llfloatergroupinvite.h
index f6a3ca5550..657e5711f0 100644
--- a/indra/newview/llfloatergroupinvite.h
+++ b/indra/newview/llfloatergroupinvite.h
@@ -37,7 +37,7 @@ class LLFloaterGroupInvite
public:
virtual ~LLFloaterGroupInvite();
- static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL);
+ static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL, bool request_update = true);
protected:
LLFloaterGroupInvite(const LLUUID& group_id = LLUUID::null);
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index dbe7fee108..f341e2ebcb 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -38,6 +38,7 @@
#include "roles_constants.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llbutton.h"
#include "llgroupactions.h"
#include "llscrolllistctrl.h"
@@ -172,7 +173,7 @@ void LLPanelGroups::reset()
group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size()));
- getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups));
+ getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",LLAgentBenefitsMgr::current().getGroupMembershipLimit()));
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
enableButtons();
@@ -183,7 +184,7 @@ BOOL LLPanelGroups::postBuild()
childSetCommitCallback("group list", onGroupList, this);
getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.size()));
- getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups));
+ getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",LLAgentBenefitsMgr::current().getGroupMembershipLimit()));
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");
if (list)
diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp
index e2160498e9..8ebb14149c 100644
--- a/indra/newview/llfloaterhandler.cpp
+++ b/indra/newview/llfloaterhandler.cpp
@@ -26,6 +26,7 @@
#include "llfloater.h"
#include "llmediactrl.h"
+#include "llfloaterreg.h"
// register with dispatch via global object
LLFloaterHandler gFloaterHandler;
@@ -50,9 +51,15 @@ LLFloater* get_parent_floater(LLView* view)
bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLMediaCtrl *web)
{
- if (params.size() < 2) return false;
+ if (params.size() < 1) return false;
LLFloater* floater = NULL;
// *TODO: implement floater lookup by name
+
+ if (params[0].asString() == "destinations")
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("destinations");
+ return true;
+ }
if (params[0].asString() == "self")
{
if (web)
diff --git a/indra/newview/llfloaterhowto.cpp b/indra/newview/llfloaterhowto.cpp
new file mode 100644
index 0000000000..a359fb7c7d
--- /dev/null
+++ b/indra/newview/llfloaterhowto.cpp
@@ -0,0 +1,92 @@
+/**
+ * @file llfloaterhowto.cpp
+ * @brief A variant of web floater meant to open guidebook
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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 "llfloaterhowto.h"
+
+#include "llfloaterreg.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+
+
+const S32 STACK_WIDTH = 300;
+const S32 STACK_HEIGHT = 505; // content will be 500
+
+LLFloaterHowTo::LLFloaterHowTo(const Params& key) :
+ LLFloaterWebContent(key)
+{
+ mShowPageTitle = false;
+}
+
+BOOL LLFloaterHowTo::postBuild()
+{
+ LLFloaterWebContent::postBuild();
+
+ return TRUE;
+}
+
+void LLFloaterHowTo::onOpen(const LLSD& key)
+{
+ LLFloaterWebContent::Params p(key);
+ if (!p.url.isProvided() || p.url.getValue().empty())
+ {
+ std::string url = gSavedSettings.getString("GuidebookURL");
+ p.url = LLWeb::expandURLSubstitutions(url, LLSD());
+ }
+ p.show_chrome = false;
+
+ LLFloaterWebContent::onOpen(p);
+
+ if (p.preferred_media_size().isEmpty())
+ {
+ // Elements from LLFloaterWebContent did not pick up restored size (save_rect) of LLFloaterHowTo
+ // set the stack size and position (alternative to preferred_media_size)
+ LLLayoutStack *stack = getChild<LLLayoutStack>("stack1");
+ LLRect stack_rect = stack->getRect();
+ stack->reshape(STACK_WIDTH, STACK_HEIGHT);
+ stack->setOrigin(stack_rect.mLeft, stack_rect.mTop - STACK_HEIGHT);
+ stack->updateLayout();
+ }
+}
+
+LLFloaterHowTo* LLFloaterHowTo::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterHowTo>("guidebook");
+}
+
+BOOL LLFloaterHowTo::handleKeyHere(KEY key, MASK mask)
+{
+ BOOL handled = FALSE;
+
+ if (KEY_F1 == key )
+ {
+ closeFloater();
+ handled = TRUE;
+ }
+
+ return handled;
+}
diff --git a/indra/newview/llfloaterhowto.h b/indra/newview/llfloaterhowto.h
new file mode 100644
index 0000000000..d8da355600
--- /dev/null
+++ b/indra/newview/llfloaterhowto.h
@@ -0,0 +1,58 @@
+/**
+ * @file llfloaterhowto.h
+ * @brief A variant of web floater meant to open guidebook
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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_LLFLOATERHOWTO_H
+#define LL_LLFLOATERHOWTO_H
+
+#include "llfloaterwebcontent.h"
+
+class LLMediaCtrl;
+
+
+class LLFloaterHowTo :
+ public LLFloaterWebContent
+{
+public:
+ LOG_CLASS(LLFloaterHowTo);
+
+ typedef LLFloaterWebContent::Params Params;
+
+ LLFloaterHowTo(const Params& key);
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL handleKeyHere(KEY key, MASK mask) override;
+
+ static LLFloaterHowTo* getInstance();
+
+ bool matchesKey(const LLSD& key) override { return true; /*single instance*/ };
+
+private:
+ BOOL postBuild() override;
+};
+
+#endif // LL_LLFLOATERHOWTO_H
+
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index d4b0fa85ab..028c922a4d 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -35,6 +35,7 @@
#include "llagent.h"
#include "llbutton.h"
+#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldrawable.h"
#include "lldrawpoolavatar.h"
@@ -63,8 +64,8 @@
const S32 PREVIEW_BORDER_WIDTH = 2;
const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
-const S32 PREVIEW_VPAD = -24; // yuk, hard coded
-const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
+const S32 PREVIEW_VPAD = -24 + 35; // yuk, hard coded
+const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16 + 35;
const S32 PREVIEW_TEXTURE_HEIGHT = 320;
//-----------------------------------------------------------------------------
@@ -115,8 +116,14 @@ BOOL LLFloaterImagePreview::postBuild()
mSculptedPreview = new LLImagePreviewSculpted(256, 256);
mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
- if (mRawImagep->getWidth() * mRawImagep->getHeight () <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
- getChildView("lossless_check")->setEnabled(TRUE);
+ if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
+ {
+ // We want "lossless_check" to be unchecked when it is disabled, regardless of
+ // LosslessJ2CUpload state, so only assign control when enabling checkbox
+ LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>("lossless_check");
+ check_box->setEnabled(TRUE);
+ check_box->setControlVariable(gSavedSettings.getControl("LosslessJ2CUpload"));
+ }
}
else
{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 21420b122b..9c84fa1991 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -54,9 +54,15 @@
#include "llcallbacklist.h"
#include "llworld.h"
#include "llsdserialize.h"
+#include "llviewermenu.h" // is_agent_mappable
#include "llviewerobjectlist.h"
#include "boost/foreach.hpp"
+
+const S32 EVENTS_PER_IDLE_LOOP_CURRENT_SESSION = 80;
+const S32 EVENTS_PER_IDLE_LOOP_BACKGROUND = 40;
+const F32 EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE = 0.01f; // process a minimum of 1% of total events per frame
+
//
// LLFloaterIMContainer
//
@@ -66,7 +72,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
mConversationsRoot(NULL),
mConversationsEventStream("ConversationsEvents"),
mInitialized(false),
- mIsFirstLaunch(true)
+ mIsFirstLaunch(true),
+ mConversationEventQueue()
{
mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction, this, _2));
@@ -304,12 +311,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
LLIconCtrl* icon = 0;
+ bool is_in_group = gAgent.isInGroup(session_id, TRUE);
+ LLUUID icon_id;
- if(gAgent.isInGroup(session_id, TRUE))
+ if (is_in_group)
{
LLGroupIconCtrl::Params icon_params;
icon_params.group_id = session_id;
icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+ icon_id = session_id;
mSessions[session_id] = floaterp;
floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
@@ -321,11 +331,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
LLAvatarIconCtrl::Params icon_params;
icon_params.avatar_id = avatar_id;
icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+ icon_id = avatar_id;
mSessions[session_id] = floaterp;
floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
}
+ LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+ if (floater)
+ {
+ floater->updateChatIcon(icon_id);
+ }
+
// forced resize of the floater
LLRect wrapper_rect = this->mTabContainer->getLocalRect();
floaterp->setRect(wrapper_rect);
@@ -411,8 +428,11 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
while (current_participant_model != end_participant_model)
{
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
- // Get the avatar name for this participant id from the cache and update the model
- participant_model->updateName();
+ if (participant_model)
+ {
+ // Get the avatar name for this participant id from the cache and update the model
+ participant_model->updateName();
+ }
// Next participant
current_participant_model++;
}
@@ -424,7 +444,9 @@ void LLFloaterIMContainer::idle(void* user_data)
{
LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
- if (!self->getVisible() || self->isMinimized())
+ self->idleProcessEvents();
+
+ if (!self->getVisible() || self->isMinimized())
{
return;
}
@@ -447,19 +469,26 @@ void LLFloaterIMContainer::idleUpdate()
const LLConversationItem *current_session = getCurSelectedViewModelItem();
if (current_session)
{
- // Update moderator options visibility
- LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
- LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
- bool is_moderator = isGroupModerator();
- bool can_ban = haveAbilityToBan();
- while (current_participant_model != end_participant_model)
+ if (current_session->getType() == LLConversationItem::CONV_SESSION_GROUP)
{
- LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
- participant_model->setModeratorOptionsVisible(is_moderator && participant_model->getUUID() != gAgentID);
- participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
-
- current_participant_model++;
+ // Update moderator options visibility
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+ bool is_moderator = isGroupModerator();
+ bool can_ban = haveAbilityToBan();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ if (participant_model)
+ {
+ participant_model->setModeratorOptionsVisible(is_moderator);
+ participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
+ }
+
+ current_participant_model++;
+ }
}
+
// Update floater's title as required by the currently selected session or use the default title
LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
@@ -485,13 +514,57 @@ void LLFloaterIMContainer::idleUpdate()
}
}
+void LLFloaterIMContainer::idleProcessEvents()
+{
+ LLUUID current_session_id = getSelectedSession();
+ conversations_items_deque::iterator iter = mConversationEventQueue.begin();
+ conversations_items_deque::iterator end = mConversationEventQueue.end();
+ while (iter != end)
+ {
+ std::deque<LLSD> &events = iter->second;
+ if (!events.empty())
+ {
+ S32 events_to_handle;
+ S32 query_size = (S32)events.size();
+ if (current_session_id == iter->first)
+ {
+ events_to_handle = EVENTS_PER_IDLE_LOOP_CURRENT_SESSION;
+ }
+ else
+ {
+ events_to_handle = EVENTS_PER_IDLE_LOOP_BACKGROUND;
+ }
+
+ if (events_to_handle <= query_size)
+ {
+ // Some groups can be very large and can generate huge amount of updates, scale processing up to keep up
+ events_to_handle = llmax(events_to_handle, (S32)(query_size * EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE));
+ }
+ else
+ {
+ events_to_handle = query_size;
+ }
+
+ for (S32 i = 0; i < events_to_handle; i++)
+ {
+ handleConversationModelEvent(events.back());
+ events.pop_back();
+ }
+ }
+ iter++;
+ }
+}
+
bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
{
- // For debug only
- //std::ostringstream llsd_value;
- //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
- //LL_INFOS() << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << LL_ENDL;
- // end debug
+ LLUUID id = event.get("session_uuid").asUUID();
+ mConversationEventQueue[id].push_front(event);
+ return true;
+}
+
+
+void LLFloaterIMContainer::handleConversationModelEvent(const LLSD& event)
+{
// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
// the model could change substantially and the view could echo only a portion of this model (though currently the
@@ -508,7 +581,7 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
if (!session_view)
{
// We skip events that are not associated with a session
- return false;
+ return;
}
LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ?
@@ -535,9 +608,9 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
{
LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+ LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
if (!participant_view && session_model && participant_model)
- {
- LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
+ {
if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
{
participant_view = createConversationViewParticipant(participant_model);
@@ -548,7 +621,8 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
// Add a participant view to the conversation floater
if (conversation_floater && participant_model)
{
- conversation_floater->addConversationViewParticipant(participant_model);
+ bool skip_updating = im_sessionp && im_sessionp->isGroupChat();
+ conversation_floater->addConversationViewParticipant(participant_model, !skip_updating);
}
}
else if (type == "update_participant")
@@ -571,12 +645,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
mConversationViewModel.requestSortAll();
mConversationsRoot->arrangeAll();
- if (conversation_floater)
- {
- conversation_floater->refreshConversation();
- }
-
- return false;
}
void LLFloaterIMContainer::draw()
@@ -1409,12 +1477,21 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
{
return is_single_select;
}
-
- // Beyond that point, if only the user agent is selected, everything is disabled
- if (is_single_select && (single_id == gAgentID))
- {
- return false;
- }
+
+ bool is_moderator_option = ("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item);
+
+ // Beyond that point, if only the user agent is selected, everything is disabled
+ if (is_single_select && (single_id == gAgentID))
+ {
+ if (is_moderator_option)
+ {
+ return enableModerateContextMenuItem(item, true);
+ }
+ else
+ {
+ return false;
+ }
+ }
// If the user agent is selected with others, everything is disabled
for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
@@ -1480,11 +1557,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
{
return canBanSelectedMember(single_id);
}
- else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
- {
- // *TODO : get that out of here...
- return enableModerateContextMenuItem(item);
- }
+ else if (is_moderator_option)
+ {
+ // *TODO : get that out of here...
+ return enableModerateContextMenuItem(item);
+ }
// By default, options that not explicitely disabled are enabled
return true;
@@ -1786,12 +1863,16 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
{
new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
}
+
+ // Will destroy views and delete models that are not assigned to any views
widget->destroyView();
}
// Suppress the conversation items and widgets from their respective maps
mConversationsItems.erase(uuid);
mConversationsWidgets.erase(uuid);
+ // Clear event query (otherwise reopening session in some way can bombard session with stale data)
+ mConversationEventQueue.erase(uuid);
// Don't let the focus fall IW, select and refocus on the first conversation in the list
if (change_focus)
@@ -1854,7 +1935,7 @@ LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParti
return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
}
-bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata)
+bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata, bool is_self)
{
// only group moderators can perform actions related to this "enable callback"
if (!isGroupModerator())
@@ -1874,7 +1955,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
{
return voice_channel;
}
- else if ("can_mute" == userdata)
+ else if (("can_mute" == userdata) && !is_self)
{
return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
}
@@ -1884,7 +1965,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
}
// The last invoke is used to check whether the "can_allow_text_chat" will enabled
- return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+ return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID()) && !is_self;
}
bool LLFloaterIMContainer::isGroupModerator()
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 78b3572111..b4a9d377ab 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -164,7 +164,7 @@ private:
void doToSelectedGroup(const LLSD& userdata);
static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
- bool enableModerateContextMenuItem(const std::string& userdata);
+ bool enableModerateContextMenuItem(const std::string& userdata, bool is_self = false);
LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
bool isGroupModerator();
@@ -181,6 +181,7 @@ private:
bool isParticipantListExpanded();
void idleUpdate(); // for convenience (self) from static idle
+ void idleProcessEvents();
LLButton* mExpandCollapseBtn;
LLButton* mStubCollapseBtn;
@@ -220,6 +221,7 @@ private:
LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
bool onConversationModelEvent(const LLSD& event);
+ void handleConversationModelEvent(const LLSD& event);
// Conversation list data
LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
@@ -227,7 +229,10 @@ private:
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
- LLEventStream mConversationsEventStream;
+ LLEventStream mConversationsEventStream;
+
+ typedef std::map<LLUUID, std::deque<LLSD> > conversations_items_deque;
+ conversations_items_deque mConversationEventQueue;
LLTimer mParticipantRefreshTimer;
};
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a6531ed7e1..3a850d4b68 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -67,6 +67,7 @@
#include "llviewerchat.h"
#include "lltranslate.h"
#include "llautoreplace.h"
+#include "lluiusage.h"
S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
@@ -697,6 +698,7 @@ 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);
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a4ab1af9a8..48e2b8dc14 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -160,7 +160,6 @@ void LLFloaterIMSession::onClickCloseBtn(bool)
else
{
LL_WARNS() << "Empty session with id: " << (mSessionID.asString()) << LL_ENDL;
- return;
}
LLFloaterIMSessionTab::onClickCloseBtn();
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 3aee08482b..7541bb5efe 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -32,6 +32,8 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
#include "llchatentry.h"
#include "llchathistory.h"
#include "llchiclet.h"
@@ -45,6 +47,9 @@
#include "llfloaterimnearbychat.h"
const F32 REFRESH_INTERVAL = 1.0f;
+const std::string ICN_GROUP("group_chat_icon");
+const std::string ICN_NEARBY("nearby_chat_icon");
+const std::string ICN_AVATAR("avatar_icon");
void cb_group_do_nothing()
{
@@ -465,9 +470,10 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
}
}
-
+static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View");
void LLFloaterIMSessionTab::buildConversationViewParticipant()
{
+ LL_RECORD_BLOCK_TIME(FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT);
// Clear the widget list since we are rebuilding afresh from the model
conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
while (widget_it != mConversationsWidgets.end())
@@ -491,19 +497,28 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
while (current_participant_model != end_participant_model)
{
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
- addConversationViewParticipant(participant_model);
+ if (participant_model)
+ {
+ addConversationViewParticipant(participant_model);
+ }
current_participant_model++;
}
}
-void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model)
+void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model, bool update_view)
{
+ if (!participant_model)
+ {
+ // Nothing to do if the model is inexistent
+ return;
+ }
+
// Check if the model already has an associated view
LLUUID uuid = participant_model->getUUID();
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
- if (widget)
+ if (widget && update_view)
{
updateConversationViewParticipant(uuid); // overkill?
}
@@ -522,10 +537,9 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
if (widget)
{
- mConversationsRoot->extractItem(widget);
- delete widget;
- mConversationsWidgets.erase(participant_id);
+ widget->destroyView();
}
+ mConversationsWidgets.erase(participant_id);
}
void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
@@ -693,6 +707,39 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
}
+void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id)
+{
+ if (mSession)
+ {
+ if (mSession->isP2PSessionType())
+ {
+ LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>(ICN_AVATAR);
+ icon->setVisible(true);
+ icon->setValue(id);
+ }
+ if (mSession->isAdHocSessionType())
+ {
+ LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+ icon->setVisible(true);
+ }
+ if (mSession->isGroupSessionType())
+ {
+ LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+ icon->setVisible(true);
+ icon->setValue(id);
+ }
+ }
+ else
+ {
+ if (mIsNearbyChat)
+ {
+ LLIconCtrl* icon = getChild<LLIconCtrl>(ICN_NEARBY);
+ icon->setVisible(true);
+ }
+ }
+
+}
+
void LLFloaterIMSessionTab::hideAllStandardButtons()
{
for (S32 i = 0; i < BUTTON_COUNT; i++)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 1b4922fd73..375461cfc1 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -84,7 +84,7 @@ public:
/*virtual*/ void setFocus(BOOL focus);
// Handle the left hand participant list widgets
- void addConversationViewParticipant(LLConversationItem* item);
+ void addConversationViewParticipant(LLConversationItem* item, bool update_view = true);
void removeConversationViewParticipant(const LLUUID& participant_id);
void updateConversationViewParticipant(const LLUUID& participant_id);
void refreshConversation();
@@ -103,6 +103,8 @@ public:
void restoreFloater();
void saveCollapsedState();
+ void updateChatIcon(const LLUUID& id);
+
LLView* getChatHistory();
protected:
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index ee3d633dd0..93a26f31cc 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -40,7 +40,17 @@
#include "llviewercontrol.h"
#include "llappviewer.h"
#include "llviewerjoystick.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// Require DirectInput version 8
+#define DIRECTINPUT_VERSION 0x0800
+
+#include <dinput.h>
+#endif
static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"),
sJoystickAxis1("Joystick axis 1"),
@@ -58,22 +68,51 @@ static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =
&sJoystickAxis5
};
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+
+BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
+{
+ // Note: If a single device can function as more than one DirectInput
+ // device type, it is enumerated as each device type that it supports.
+ // Capable of detecting devices like Oculus Rift
+ if (device_instance_ptr && pvRef)
+ {
+ std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+
+ LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef;
+ LLSD value = data;
+ floater->addDevice(product_name, value);
+ }
+ return DIENUM_CONTINUE;
+}
+#endif
+
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
- : LLFloater(data)
+ : LLFloater(data),
+ mHasDeviceList(false)
{
+ if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
+ {
+ LLViewerJoystick::getInstance()->init(false);
+ }
+
initFromSettings();
}
void LLFloaterJoystick::draw()
{
- bool joystick_inited = LLViewerJoystick::getInstance()->isJoystickInitialized();
- getChildView("enable_joystick")->setEnabled(joystick_inited);
- getChildView("joystick_type")->setEnabled(joystick_inited);
- std::string desc = LLViewerJoystick::getInstance()->getDescription();
- if (desc.empty()) desc = getString("NoDevice");
- getChild<LLUICtrl>("joystick_type")->setValue(desc);
-
- LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ bool joystick_inited = joystick->isJoystickInitialized();
+ if (joystick_inited != mHasDeviceList)
+ {
+ refreshListOfDevices();
+ }
+
for (U32 i = 0; i < 6; i++)
{
F32 value = joystick->getJoystickAxis(i);
@@ -110,8 +149,8 @@ BOOL LLFloaterJoystick::postBuild()
}
}
- mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick");
- childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this);
+ mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
+ childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled");
childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this);
@@ -120,6 +159,7 @@ BOOL LLFloaterJoystick::postBuild()
childSetAction("ok_btn", onClickOK, this);
refresh();
+ refreshListOfDevices();
return TRUE;
}
@@ -136,6 +176,7 @@ void LLFloaterJoystick::apply()
void LLFloaterJoystick::initFromSettings()
{
mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled");
+ mJoystickId = gSavedSettings.getLLSD("JoystickDeviceUUID");
mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0");
mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1");
@@ -205,12 +246,80 @@ void LLFloaterJoystick::initFromSettings()
void LLFloaterJoystick::refresh()
{
LLFloater::refresh();
+
initFromSettings();
}
+void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
+{
+ mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+}
+
+void LLFloaterJoystick::refreshListOfDevices()
+{
+ mJoysticksCombo->removeall();
+ std::string no_device = getString("JoystickDisabled");
+ LLSD value = LLSD::Integer(0);
+ addDevice(no_device, value);
+
+ mHasDeviceList = false;
+
+ // di8_devices_callback callback is immediate and happens in scope of getInputDevices()
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_list_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+ if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this))
+ {
+ mHasDeviceList = true;
+ }
+
+ bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet();
+
+ if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
+ (!mHasDeviceList || !is_device_id_set))
+ {
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL;
+#endif
+ std::string desc = LLViewerJoystick::getInstance()->getDescription();
+ if (!desc.empty())
+ {
+ LLSD value = LLSD::Integer(0);
+ addDevice(desc, value);
+ mHasDeviceList = true;
+ }
+ }
+
+ if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
+ {
+ if (is_device_id_set)
+ {
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+ mJoysticksCombo->selectByValue(guid);
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(1));
+ }
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(0));
+ }
+}
+
void LLFloaterJoystick::cancel()
{
gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled);
+ gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId);
gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]);
gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]);
@@ -280,7 +389,21 @@ void LLFloaterJoystick::cancel()
void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
{
LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel;
- BOOL joystick_enabled = self->mCheckJoystickEnabled->get();
+
+ LLSD value = self->mJoysticksCombo->getValue();
+ bool joystick_enabled = true;
+ if (value.isInteger())
+ {
+ // ndof already has a device selected, we are just setting it enabled or disabled
+ joystick_enabled = value.asInteger();
+ }
+ else
+ {
+ LLViewerJoystick::getInstance()->initDevice(value);
+ // else joystick is enabled, because combobox holds id of device
+ joystick_enabled = true;
+ }
+ gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
BOOL flycam_enabled = self->mCheckFlycamEnabled->get();
if (!joystick_enabled || !flycam_enabled)
@@ -292,6 +415,12 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
joystick->toggleFlycam();
}
}
+
+ std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
+ gSavedSettings.setString("JoystickDeviceUUID", device_id);
+ LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
+
+ self->refreshListOfDevices();
}
void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel)
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index a1b5951389..1d46efd3f6 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -31,6 +31,7 @@
#include "llstatview.h"
class LLCheckBoxCtrl;
+class LLComboBox;
class LLFloaterJoystick : public LLFloater
{
@@ -45,8 +46,11 @@ public:
virtual void draw();
static void setSNDefaults();
+ void addDevice(std::string &name, LLSD& value);
+
protected:
+ void refreshListOfDevices();
void onClose(bool app_quitting);
void onClickCloseBtn(bool app_quitting);
@@ -65,6 +69,7 @@ private:
private:
// Device prefs
bool mJoystickEnabled;
+ LLSD mJoystickId;
S32 mJoystickAxis[7];
bool m3DCursor;
bool mAutoLeveling;
@@ -85,8 +90,10 @@ private:
F32 mFlycamFeathering;
// Controls that can disable the flycam
- LLCheckBoxCtrl *mCheckJoystickEnabled;
LLCheckBoxCtrl *mCheckFlycamEnabled;
+ LLComboBox *mJoysticksCombo;
+
+ bool mHasDeviceList;
// stats view
LLStatBar* mAxisStatsBar[6];
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 3098c6d118..af0e56e448 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -79,9 +79,11 @@
#include "lltrans.h"
#include "llpanelexperiencelisteditor.h"
#include "llpanelexperiencepicker.h"
+#include "llpanelenvironment.h"
#include "llexperiencecache.h"
#include "llgroupactions.h"
+#include "llenvironment.h"
const F64 COVENANT_REFRESH_TIME_SEC = 60.0f;
@@ -139,6 +141,38 @@ protected:
LLPanelExperienceListEditor* mBlocked;
};
+
+class LLPanelLandEnvironment
+ : public LLPanelEnvironmentInfo
+{
+public:
+ LLPanelLandEnvironment(LLSafeHandle<LLParcelSelection>& parcelp);
+
+ virtual bool isRegion() const override { return false; }
+ virtual bool isLargeEnough() override
+ {
+ LLParcel *parcelp = mParcel->getParcel();
+ return ((parcelp) ? (parcelp->getArea() >= MINIMUM_PARCEL_SIZE) : false);
+ }
+
+ virtual BOOL postBuild() override;
+ virtual void refresh() override;
+
+ virtual LLParcel * getParcel() override;
+
+ virtual bool canEdit() override;
+ virtual S32 getParcelId() override;
+
+protected:
+ virtual void refreshFromSource() override;
+
+ bool isSameRegion();
+
+ LLSafeHandle<LLParcelSelection> & mParcel;
+ S32 mLastParcelId;
+};
+
+
// inserts maturity info(icon and text) into target textbox
// names_floater - pointer to floater which contains strings with maturity icons filenames
// str_to_parse is string in format "txt1[MATURITY]txt2" where maturity icon and text will be inserted instead of [MATURITY]
@@ -227,7 +261,7 @@ LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant()
// static
void LLFloaterLand::refreshAll()
{
- LLFloaterLand* land_instance = LLFloaterReg::getTypedInstance<LLFloaterLand>("about_land");
+ LLFloaterLand* land_instance = LLFloaterReg::findTypedInstance<LLFloaterLand>("about_land");
if(land_instance)
{
land_instance->refresh();
@@ -278,6 +312,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed)
mFactoryMap["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this);
mFactoryMap["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this);
mFactoryMap["land_experiences_panel"] = LLCallbackMap(createPanelLandExperiences, this);
+ mFactoryMap["land_environment_panel"] = LLCallbackMap(createPanelLandEnvironment, this);
sObserver = new LLParcelSelectionObserver();
LLViewerParcelMgr::getInstance()->addObserver( sObserver );
@@ -319,6 +354,7 @@ void LLFloaterLand::refresh()
mPanelAccess->refresh();
mPanelCovenant->refresh();
mPanelExperiences->refresh();
+ mPanelEnvironment->refresh();
}
@@ -387,6 +423,14 @@ void* LLFloaterLand::createPanelLandExperiences(void* data)
return self->mPanelExperiences;
}
+//static
+void* LLFloaterLand::createPanelLandEnvironment(void* data)
+{
+ LLFloaterLand* self = (LLFloaterLand*)data;
+ self->mPanelEnvironment = new LLPanelLandEnvironment(self->mParcel);
+ return self->mPanelEnvironment;
+}
+
//---------------------------------------------------------------------------
// LLPanelLandGeneral
@@ -2209,7 +2253,7 @@ void LLPanelLandOptions::refreshSearch()
// effort to reduce search spam from small parcels. See also
// the search crawler "grid-crawl.py" in secondlife.com/doc/app/search/ JC
const S32 MIN_PARCEL_AREA_FOR_SEARCH = 128;
- bool large_enough = parcel->getArea() > MIN_PARCEL_AREA_FOR_SEARCH;
+ bool large_enough = parcel->getArea() >= MIN_PARCEL_AREA_FOR_SEARCH;
if (large_enough)
{
if (can_change)
@@ -3268,3 +3312,144 @@ void LLPanelLandExperiences::refresh()
refreshPanel(mAllowed, EXPERIENCE_KEY_TYPE_ALLOWED);
refreshPanel(mBlocked, EXPERIENCE_KEY_TYPE_BLOCKED);
}
+
+//=========================================================================
+
+LLPanelLandEnvironment::LLPanelLandEnvironment(LLParcelSelectionHandle& parcel) :
+ LLPanelEnvironmentInfo(),
+ mParcel(parcel),
+ mLastParcelId(INVALID_PARCEL_ID)
+{
+}
+
+BOOL LLPanelLandEnvironment::postBuild()
+{
+ if (!LLPanelEnvironmentInfo::postBuild())
+ return FALSE;
+
+ getChild<LLUICtrl>(BTN_USEDEFAULT)->setLabelArg("[USEDEFAULT]", getString(STR_LABEL_USEREGION));
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setVisible(FALSE);
+ getChild<LLUICtrl>(PNL_REGION_MSG)->setVisible(FALSE);
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(TRUE);
+
+ return TRUE;
+}
+
+void LLPanelLandEnvironment::refresh()
+{
+ if (gDisconnected)
+ return;
+
+ commitDayLenOffsetChanges(false); // commit unsaved changes if any
+
+ if (!isSameRegion())
+ {
+ setCrossRegion(true);
+ mCurrentEnvironment.reset();
+ mLastParcelId = INVALID_PARCEL_ID;
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ setControlsEnabled(false);
+ return;
+ }
+
+ if (mLastParcelId != getParcelId())
+ {
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ mCurrentEnvironment.reset();
+ }
+
+ if (!mCurrentEnvironment && mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ refreshFromSource();
+ return;
+ }
+
+ LLPanelEnvironmentInfo::refresh();
+}
+
+void LLPanelLandEnvironment::refreshFromSource()
+{
+ LLParcel *parcel = getParcel();
+
+ if (!LLEnvironment::instance().isExtendedEnvironmentEnabled())
+ {
+ setNoEnvironmentSupport(true);
+ setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ return;
+ }
+ setNoEnvironmentSupport(false);
+
+ if (!parcel)
+ {
+ setNoSelection(true);
+ setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ return;
+ }
+
+ setNoSelection(false);
+ if (isSameRegion())
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Requesting environment for parcel " << parcel->getLocalID() << ", known version " << mCurEnvVersion << LL_ENDL;
+ setCrossRegion(false);
+
+ LLHandle<LLPanel> that_h = getHandle();
+
+ if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // to mark as requesting
+ mCurEnvVersion = parcel->getParcelEnvironmentVersion();
+ }
+ mLastParcelId = parcel->getLocalID();
+
+ LLEnvironment::instance().requestParcel(parcel->getLocalID(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)
+ {
+ LLPanelLandEnvironment *that = (LLPanelLandEnvironment*)that_h.get();
+ if (!that) return;
+ that->mLastParcelId = parcel_id;
+ that->onEnvironmentReceived(parcel_id, envifo);
+ });
+ }
+ else
+ {
+ setCrossRegion(true);
+ mCurrentEnvironment.reset();
+ mLastParcelId = INVALID_PARCEL_ID;
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ }
+ setControlsEnabled(false);
+}
+
+
+bool LLPanelLandEnvironment::isSameRegion()
+{
+ LLViewerRegion* regionp = LLViewerParcelMgr::instance().getSelectionRegion();
+
+ return (!regionp || (regionp->getRegionID() == gAgent.getRegion()->getRegionID()));
+}
+
+LLParcel *LLPanelLandEnvironment::getParcel()
+{
+ return mParcel->getParcel();
+}
+
+
+bool LLPanelLandEnvironment::canEdit()
+{
+ LLParcel *parcel = getParcel();
+ if (!parcel)
+ return false;
+
+ return LLEnvironment::instance().canAgentUpdateParcelEnvironment(parcel) && mAllowOverride;
+}
+
+S32 LLPanelLandEnvironment::getParcelId()
+{
+ LLParcel *parcel = getParcel();
+ if (!parcel)
+ return INVALID_PARCEL_ID;
+
+ return parcel->getLocalID();
+}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 0c49d78a20..5d9b411f04 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -67,6 +67,7 @@ class LLPanelLandRenters;
class LLPanelLandCovenant;
class LLParcel;
class LLPanelLandExperiences;
+class LLPanelLandEnvironment;
class LLFloaterLand
: public LLFloater
@@ -103,6 +104,7 @@ protected:
static void* createPanelLandMedia(void* data);
static void* createPanelLandAccess(void* data);
static void* createPanelLandExperiences(void* data);
+ static void* createPanelLandEnvironment(void* data);
static void* createPanelLandBan(void* data);
@@ -119,6 +121,7 @@ protected:
LLPanelLandAccess* mPanelAccess;
LLPanelLandCovenant* mPanelCovenant;
LLPanelLandExperiences* mPanelExperiences;
+ LLPanelLandEnvironment *mPanelEnvironment;
LLSafeHandle<LLParcelSelection> mParcel;
diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp
index f34760a6bf..749a3d2686 100644
--- a/indra/newview/llfloaterlandholdings.cpp
+++ b/indra/newview/llfloaterlandholdings.cpp
@@ -51,6 +51,9 @@
#include "llgroupactions.h"
+const std::string LINDEN_HOMES_SKU = "131";
+bool LLFloaterLandHoldings::sHasLindenHome = false;
+
// protected
LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key)
: LLFloater(key),
@@ -148,10 +151,24 @@ void LLFloaterLandHoldings::refresh()
void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
{
LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings");
-
- // Is this packet from an old, closed window?
+ S32 count = msg->getNumberOfBlocks("QueryData");
+ std::string land_sku;
+ sHasLindenHome = false;
if (!self)
{
+ for (S32 i = 0; i < count; i++)
+ {
+ if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 )
+ {
+ msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
+
+ if (LINDEN_HOMES_SKU == land_sku)
+ {
+ sHasLindenHome = true;
+ return;
+ }
+ }
+ }
return;
}
@@ -174,12 +191,9 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
F32 global_x;
F32 global_y;
std::string sim_name;
- std::string land_sku;
std::string land_type;
- S32 i;
- S32 count = msg->getNumberOfBlocks("QueryData");
- for (i = 0; i < count; i++)
+ for (S32 i = 0; i < count; i++)
{
msg->getUUID("QueryData", "OwnerID", owner_id, i);
msg->getString("QueryData", "Name", name, i);
@@ -196,6 +210,10 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
msg->getStringFast( _PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
LL_INFOS() << "Land sku: " << land_sku << LL_ENDL;
land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
+ if (LINDEN_HOMES_SKU == land_sku)
+ {
+ sHasLindenHome = true;
+ }
}
else
{
diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h
index d1d510bb40..90e75b1062 100644
--- a/indra/newview/llfloaterlandholdings.h
+++ b/indra/newview/llfloaterlandholdings.h
@@ -57,6 +57,8 @@ public:
static void onGrantList(void* data);
+ static bool sHasLindenHome;
+
protected:
void refreshAggregates();
diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp
index 10cce3bd22..595d584799 100644
--- a/indra/newview/llfloaterlinkreplace.cpp
+++ b/indra/newview/llfloaterlinkreplace.cpp
@@ -32,6 +32,8 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llnotifications.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
@@ -142,37 +144,72 @@ void LLFloaterLinkReplace::onStartClicked()
LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL;
return;
}
+
+ const LLUUID& source_item_id = gInventory.getLinkedItemID(mSourceUUID);
+ LLViewerInventoryItem *source_item = gInventory.getItem(source_item_id);
+ const LLUUID& target_item_id = gInventory.getLinkedItemID(mTargetUUID);
+ LLViewerInventoryItem *target_item = gInventory.getItem(target_item_id);
- LLInventoryModel::cat_array_t cat_array;
- LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
- gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
- cat_array,
- mRemainingInventoryItems,
- LLInventoryModel::INCLUDE_TRASH,
- is_linked_item_match);
- LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
- if (mRemainingInventoryItems.size() > 0)
+ LLNotification::Params params("ConfirmReplaceLink");
+ params.functor.function(boost::bind(&LLFloaterLinkReplace::onStartClickedResponse, this, _1, _2));
+ if (source_item && source_item->isWearableType() && source_item->getWearableType() <= LLWearableType::WT_EYES)
{
- LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
- if (target_item)
+ if(target_item && target_item->isWearableType() && source_item->getWearableType() == target_item->getWearableType())
{
- mRemainingItems = (U32)mRemainingInventoryItems.size();
-
- LLStringUtil::format_map_t args;
- args["NUM"] = llformat("%d", mRemainingItems);
- mStatusText->setText(getString("ItemsRemaining", args));
-
- mStartBtn->setEnabled(FALSE);
- mRefreshBtn->setEnabled(FALSE);
-
- mEventTimer.start();
- tick();
+ LLNotifications::instance().forceResponse(params, 0);
}
else
{
- mStatusText->setText(getString("TargetNotFound"));
- LL_WARNS() << "Link replace target not found." << LL_ENDL;
+ LLSD args;
+ args["TYPE"] = LLWearableType::getTypeName(source_item->getWearableType());
+ params.substitutions(args);
+ LLNotifications::instance().add(params);
+ }
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+}
+
+void LLFloaterLinkReplace::onStartClickedResponse(const LLSD& notification, const LLSD& response)
+{
+
+ if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
+ {
+
+ LLInventoryModel::cat_array_t cat_array;
+ LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cat_array,
+ mRemainingInventoryItems,
+ LLInventoryModel::INCLUDE_TRASH,
+ is_linked_item_match);
+ LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
+
+ if (mRemainingInventoryItems.size() > 0)
+ {
+ LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
+ if (target_item)
+ {
+ mRemainingItems = (U32)mRemainingInventoryItems.size();
+
+ LLStringUtil::format_map_t args;
+ args["NUM"] = llformat("%d", mRemainingItems);
+ mStatusText->setText(getString("ItemsRemaining", args));
+
+ mStartBtn->setEnabled(FALSE);
+ mRefreshBtn->setEnabled(FALSE);
+
+ mEventTimer.start();
+ tick();
+ }
+ else
+ {
+ mStatusText->setText(getString("TargetNotFound"));
+ LL_WARNS() << "Link replace target not found." << LL_ENDL;
+ }
}
}
}
diff --git a/indra/newview/llfloaterlinkreplace.h b/indra/newview/llfloaterlinkreplace.h
index dd5c301206..060773f93e 100644
--- a/indra/newview/llfloaterlinkreplace.h
+++ b/indra/newview/llfloaterlinkreplace.h
@@ -94,6 +94,7 @@ public:
private:
void checkEnableStart();
void onStartClicked();
+ void onStartClickedResponse(const LLSD& notification, const LLSD& response);
void decreaseOpenItemCount();
void updateFoundLinks();
void processBatch(LLInventoryModel::item_array_t items);
diff --git a/indra/newview/llfloaterloadprefpreset.cpp b/indra/newview/llfloaterloadprefpreset.cpp
index 403db35cc0..8ed76b1df4 100644
--- a/indra/newview/llfloaterloadprefpreset.cpp
+++ b/indra/newview/llfloaterloadprefpreset.cpp
@@ -42,7 +42,8 @@ LLFloaterLoadPrefPreset::LLFloaterLoadPrefPreset(const LLSD &key)
// virtual
BOOL LLFloaterLoadPrefPreset::postBuild()
-{ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+{
+ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (preferences)
{
preferences->addDependentFloater(this);
@@ -57,14 +58,27 @@ BOOL LLFloaterLoadPrefPreset::postBuild()
void LLFloaterLoadPrefPreset::onOpen(const LLSD& key)
{
mSubdirectory = key.asString();
- std::string floater_title = getString(std::string("title_") + mSubdirectory);
-
- setTitle(floater_title);
+ std::string title_type = std::string("title_") + mSubdirectory;
+ if (hasString(title_type))
+ {
+ std::string floater_title = getString(title_type);
+ setTitle(floater_title);
+ }
+ else
+ {
+ LL_WARNS() << title_type << " not found" << LL_ENDL;
+ setTitle(title_type);
+ }
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
EDefaultOptions option = DEFAULT_TOP;
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+ std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+ if (!preset_graphic_active.empty())
+ {
+ combo->setSimple(preset_graphic_active);
+ }
}
void LLFloaterLoadPrefPreset::onPresetsListChange()
@@ -73,6 +87,11 @@ void LLFloaterLoadPrefPreset::onPresetsListChange()
EDefaultOptions option = DEFAULT_TOP;
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option);
+ std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
+ if (!preset_graphic_active.empty())
+ {
+ combo->setSimple(preset_graphic_active);
+ }
}
void LLFloaterLoadPrefPreset::onBtnCancel()
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 889d017389..524162ba51 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -103,14 +103,17 @@ void LLPanelMarketplaceListings::buildAllPanels()
panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");
panel->getFilter().setFilterMarketplaceActiveFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
panel->getFilter().markDefault();
panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");
panel->getFilter().setFilterMarketplaceInactiveFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
panel->getFilter().markDefault();
panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");
panel->getFilter().setFilterMarketplaceUnassociatedFolders();
panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
panel->getFilter().markDefault();
// Set the tab panel
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index c4186132fe..d9edd4dc30 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -27,7 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llmodelloader.h"
-#include "lldaeloader.h"
+#include "llmodelpreview.h"
#include "llfloatermodelpreview.h"
@@ -40,16 +40,7 @@
#include "llagent.h"
#include "llbutton.h"
#include "llcombobox.h"
-#include "lldatapacker.h"
-#include "lldrawable.h"
-#include "llrender.h"
-#include "llface.h"
-#include "lleconomy.h"
#include "llfocusmgr.h"
-#include "llfloaterperms.h"
-#include "lliconctrl.h"
-#include "llmatrix4a.h"
-#include "llmenubutton.h"
#include "llmeshrepository.h"
#include "llnotificationsutil.h"
#include "llsdutil_math.h"
@@ -57,44 +48,26 @@
#include "lltextbox.h"
#include "lltoolmgr.h"
#include "llui.h"
-#include "llvector4a.h"
-#include "llviewercamera.h"
#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
#include "pipeline.h"
-#include "lluictrlfactory.h"
#include "llviewercontrol.h"
-#include "llviewermenu.h"
-#include "llviewermenufile.h"
-#include "llviewerregion.h"
-#include "llviewertexturelist.h"
+#include "llviewermenufile.h" //LLFilePickerThread
#include "llstring.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
-#include "llradiogroup.h"
-#include "llsdserialize.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
-#include "lltoggleablemenu.h"
+#include "lltabcontainer.h"
#include "lltrans.h"
-#include "llvfile.h"
-#include "llvfs.h"
#include "llcallbacklist.h"
-#include "llviewerobjectlist.h"
-#include "llanimationstates.h"
+#include "llviewertexteditor.h"
#include "llviewernetwork.h"
-#include "llviewershadermgr.h"
-#include "glod/glod.h"
-#include <boost/algorithm/string.hpp>
//static
S32 LLFloaterModelPreview::sUploadAmount = 10;
LLFloaterModelPreview* LLFloaterModelPreview::sInstance = NULL;
-bool LLModelPreview::sIgnoreLoadedCallback = false;
-
// "Retain%" decomp parameter has values from 0.0 to 1.0 by 0.01
// But according to the UI spec for upload model floater, this parameter
// should be represented by Retain spinner with values from 1 to 100 by 1.
@@ -107,110 +80,20 @@ const double RETAIN_COEFFICIENT = 100;
// should be represented by Smooth combobox with only 10 values.
// So this const is used as a size of Smooth combobox list.
const S32 SMOOTH_VALUES_NUMBER = 10;
+const S32 PREVIEW_RENDER_SIZE = 1024;
+const F32 PREVIEW_CAMERA_DISTANCE = 16.f;
-void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
-
-
-std::string lod_name[NUM_LOD+1] =
-{
- "lowest",
- "low",
- "medium",
- "high",
- "I went off the end of the lod_name array. Me so smart."
-};
-
-std::string lod_triangles_name[NUM_LOD+1] =
+class LLMeshFilePicker : public LLFilePickerThread
{
- "lowest_triangles",
- "low_triangles",
- "medium_triangles",
- "high_triangles",
- "I went off the end of the lod_triangles_name array. Me so smart."
-};
-
-std::string lod_vertices_name[NUM_LOD+1] =
-{
- "lowest_vertices",
- "low_vertices",
- "medium_vertices",
- "high_vertices",
- "I went off the end of the lod_vertices_name array. Me so smart."
-};
+public:
+ LLMeshFilePicker(LLModelPreview* mp, S32 lod);
+ virtual void notify(const std::vector<std::string>& filenames);
-std::string lod_status_name[NUM_LOD+1] =
-{
- "lowest_status",
- "low_status",
- "medium_status",
- "high_status",
- "I went off the end of the lod_status_name array. Me so smart."
+private:
+ LLModelPreview* mMP;
+ S32 mLOD;
};
-std::string lod_icon_name[NUM_LOD+1] =
-{
- "status_icon_lowest",
- "status_icon_low",
- "status_icon_medium",
- "status_icon_high",
- "I went off the end of the lod_status_name array. Me so smart."
-};
-
-std::string lod_status_image[NUM_LOD+1] =
-{
- "ModelImport_Status_Good",
- "ModelImport_Status_Warning",
- "ModelImport_Status_Error",
- "I went off the end of the lod_status_image array. Me so smart."
-};
-
-std::string lod_label_name[NUM_LOD+1] =
-{
- "lowest_label",
- "low_label",
- "medium_label",
- "high_label",
- "I went off the end of the lod_label_name array. Me so smart."
-};
-
-BOOL stop_gloderror()
-{
- GLuint error = glodGetError();
-
- if (error != GLOD_NO_ERROR)
- {
- LL_WARNS() << "GLOD error detected, cannot generate LOD: " << std::hex << error << LL_ENDL;
- return TRUE;
- }
-
- return FALSE;
-}
-
-LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& material)
-{
- LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_PREVIEW);
-
- if (texture)
- {
- if (texture->getDiscardLevel() > -1)
- {
- gGL.getTexUnit(0)->bind(texture, true);
- return texture;
- }
- }
-
- return NULL;
-}
-
-std::string stripSuffix(std::string name)
-{
- if ((name.find("_LOD") != -1) || (name.find("_PHYS") != -1))
- {
- return name.substr(0, name.rfind('_'));
- }
- return name;
-}
-
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
{
@@ -220,6 +103,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)
{
+ if(LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+
if (filenames.size() > 0)
{
mMP->loadModel(filenames[0], mLOD);
@@ -231,37 +119,16 @@ void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)
}
}
-void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)
-{
- LLModelLoader::scene::iterator base_iter = scene.begin();
- bool found = false;
- while (!found && (base_iter != scene.end()))
- {
- matOut = base_iter->first;
-
- LLModelLoader::model_instance_list::iterator base_instance_iter = base_iter->second.begin();
- while (!found && (base_instance_iter != base_iter->second.end()))
- {
- LLModelInstance& base_instance = *base_instance_iter++;
- LLModel* base_model = base_instance.mModel;
-
- if (base_model && (base_model->mLabel == name_to_match))
- {
- baseModelOut = base_model;
- return;
- }
- }
- base_iter++;
- }
-}
-
//-----------------------------------------------------------------------------
// LLFloaterModelPreview()
//-----------------------------------------------------------------------------
LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) :
LLFloaterModelUploadBase(key),
mUploadBtn(NULL),
-mCalculateBtn(NULL)
+mCalculateBtn(NULL),
+mUploadLogText(NULL),
+mTabContainer(NULL),
+mAvatarTabIndex(0)
{
sInstance = this;
mLastMouseX = 0;
@@ -304,10 +171,11 @@ BOOL LLFloaterModelPreview::postBuild()
getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true));
}
- childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
- childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
- childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
- childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);
+ // Upload/avatar options, they need to refresh errors/notifications
+ childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+ childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+ childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
+ childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL);
childSetTextArg("status", "[STATUS]", getString("status_idle"));
@@ -318,10 +186,6 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this);
- childSetCommitCallback("upload_skin", onUploadSkinCommit, this);
- childSetCommitCallback("upload_joints", onUploadJointsCommit, this);
- childSetCommitCallback("lock_scale_if_joint_position", onUploadJointsCommit, this);
-
childSetCommitCallback("import_scale", onImportScaleCommit, this);
childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
@@ -330,13 +194,20 @@ BOOL LLFloaterModelPreview::postBuild()
getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
- getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onShowSkinWeightChecked, this, _1));
+ getChild<LLCheckBoxCtrl>("show_joint_overrides")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
getChild<LLCheckBoxCtrl>("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1));
childDisable("upload_skin");
childDisable("upload_joints");
childDisable("lock_scale_if_joint_position");
+ childSetVisible("skin_too_many_joints", false);
+ childSetVisible("skin_unknown_joint", false);
+
+ childSetVisible("warning_title", false);
+ childSetVisible("warning_message", false);
+
initDecompControls();
LLView* preview_panel = getChild<LLView>("preview_panel");
@@ -392,6 +263,12 @@ BOOL LLFloaterModelPreview::postBuild()
mUploadBtn = getChild<LLButton>("ok_btn");
mCalculateBtn = getChild<LLButton>("calculate_btn");
+ mUploadLogText = getChild<LLViewerTextEditor>("log_text");
+ mTabContainer = getChild<LLTabContainer>("import_tab");
+
+ LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
+ mAvatarTabIndex = mTabContainer->getIndexForPanel(panel);
+ panel->getChild<LLScrollListCtrl>("joints_list")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onJointListSelection, this));
if (LLConvexDecomposition::getInstance() != NULL)
{
@@ -408,6 +285,24 @@ BOOL LLFloaterModelPreview::postBuild()
}
//-----------------------------------------------------------------------------
+// reshape()
+//-----------------------------------------------------------------------------
+
+void LLFloaterModelPreview::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloaterModelUploadBase::reshape(width, height, called_from_parent);
+
+ LLView* preview_panel = getChild<LLView>("preview_panel");
+ LLRect rect = preview_panel->getRect();
+
+ if (rect != mPreviewRect)
+ {
+ mModelPreview->refresh();
+ mPreviewRect = preview_panel->getRect();
+ }
+}
+
+//-----------------------------------------------------------------------------
// LLFloaterModelPreview()
//-----------------------------------------------------------------------------
LLFloaterModelPreview::~LLFloaterModelPreview()
@@ -430,18 +325,95 @@ void LLFloaterModelPreview::initModelPreview()
delete mModelPreview;
}
- mModelPreview = new LLModelPreview(512, 512, this );
- mModelPreview->setPreviewTarget(16.f);
+ 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);
+
+ while ((tex_width << 1) < max_width)
+ {
+ tex_width <<= 1;
+ }
+ while ((tex_height << 1) < max_height)
+ {
+ tex_height <<= 1;
+ }
+
+ mModelPreview = new LLModelPreview(tex_width, tex_height, this);
+ mModelPreview->setPreviewTarget(PREVIEW_CAMERA_DISTANCE);
mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5));
- mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1));
+ mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::modelUpdated, this, _1));
+}
+
+void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
+{
+ if (mModelPreview)
+ {
+ auto name = ctrl->getName();
+ bool value = ctrl->getValue().asBoolean();
+ // update the option and notifications
+ // (this is a bit convoluted, because of the current structure of mModelPreview)
+ if (name == "upload_skin")
+ {
+ childSetValue("show_skin_weight", value);
+ mModelPreview->mViewOption["show_skin_weight"] = value;
+ if (!value)
+ {
+ mModelPreview->mViewOption["show_joint_overrides"] = false;
+ mModelPreview->mViewOption["show_joint_positions"] = false;
+ childSetValue("show_joint_overrides", false);
+ childSetValue("show_joint_positions", false);
+ }
+ }
+ else if (name == "upload_joints")
+ {
+ if (mModelPreview->mViewOption["show_skin_weight"])
+ {
+ childSetValue("show_joint_overrides", value);
+ mModelPreview->mViewOption["show_joint_overrides"] = value;
+ }
+ }
+ else if (name == "upload_textures")
+ {
+ childSetValue("show_textures", value);
+ mModelPreview->mViewOption["show_textures"] = value;
+ }
+ else if (name == "lock_scale_if_joint_position")
+ {
+ mModelPreview->mViewOption["lock_scale_if_joint_position"] = value;
+ }
+
+ mModelPreview->refresh(); // a 'dirty' flag for render
+ mModelPreview->resetPreviewTarget();
+ mModelPreview->clearBuffers();
+ mModelPreview->mDirty = true;
+ }
+ // set the button visible, it will be refreshed later
+ toggleCalculateButton(true);
+}
+
+void LLFloaterModelPreview::onShowSkinWeightChecked(LLUICtrl* ctrl)
+{
+ if (mModelPreview)
+ {
+ mModelPreview->mCameraOffset.clearVec();
+ onViewOptionChecked(ctrl);
+ }
}
void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl)
{
if (mModelPreview)
{
- mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()];
-
+ auto name = ctrl->getName();
+ mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name];
+ if (name == "show_physics")
+ {
+ auto enabled = mModelPreview->mViewOption[name];
+ childSetEnabled("physics_explode", enabled);
+ childSetVisible("physics_explode", enabled);
+ }
mModelPreview->refresh();
}
}
@@ -476,6 +448,12 @@ void LLFloaterModelPreview::disableViewOption(const std::string& option)
setViewOptionEnabled(option, false);
}
+void LLFloaterModelPreview::loadHighLodModel()
+{
+ mModelPreview->mLookUpLodFiles = true;
+ loadModel(3);
+}
+
void LLFloaterModelPreview::loadModel(S32 lod)
{
mModelPreview->mLoading = true;
@@ -497,20 +475,16 @@ void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, boo
void LLFloaterModelPreview::onClickCalculateBtn()
{
+ clearLogTab();
+ addStringToLog("Calculating model data.", false);
mModelPreview->rebuildUploadData();
bool upload_skinweights = childGetValue("upload_skin").asBoolean();
bool upload_joint_positions = childGetValue("upload_joints").asBoolean();
bool lock_scale_if_joint_position = childGetValue("lock_scale_if_joint_position").asBoolean();
- if (upload_joint_positions)
- {
- // Diagnostic message showing list of joints for which joint offsets are defined.
- // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages().
- mModelPreview->getPreviewAvatar()->showAttachmentOverrides();
- }
-
- mUploadModelUrl.clear();
+ mUploadModelUrl.clear();
+ mModelPhysicsFee.clear();
gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
childGetValue("upload_textures").asBoolean(),
@@ -522,6 +496,132 @@ void LLFloaterModelPreview::onClickCalculateBtn()
mUploadBtn->setEnabled(false);
}
+// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function
+void add_row_to_list(LLScrollListCtrl *listp,
+ LLScrollListCell::Params &cell_params,
+ const LLSD &item_value,
+ const std::string &name,
+ const LLSD &vx,
+ const LLSD &vy,
+ const LLSD &vz)
+{
+ LLScrollListItem::Params item_params;
+ item_params.value = item_value;
+
+ cell_params.column = "model_name";
+ cell_params.value = name;
+
+ item_params.columns.add(cell_params);
+
+ cell_params.column = "axis_x";
+ cell_params.value = vx;
+ item_params.columns.add(cell_params);
+
+ cell_params.column = "axis_y";
+ cell_params.value = vy;
+ item_params.columns.add(cell_params);
+
+ cell_params.column = "axis_z";
+ cell_params.value = vz;
+
+ item_params.columns.add(cell_params);
+
+ listp->addRow(item_params);
+}
+
+void populate_list_with_overrides(LLScrollListCtrl *listp, const LLJointOverrideData &data, bool include_overrides)
+{
+ if (data.mModelsNoOverrides.empty() && data.mPosOverrides.empty())
+ {
+ return;
+ }
+
+ static const std::string no_override_placeholder = "-";
+
+ S32 count = 0;
+ LLScrollListCell::Params cell_params;
+ cell_params.font = LLFontGL::getFontSansSerif();
+ // Start out right justifying numeric displays
+ cell_params.font_halign = LLFontGL::HCENTER;
+
+ std::map<std::string, LLVector3>::const_iterator map_iter = data.mPosOverrides.begin();
+ std::map<std::string, LLVector3>::const_iterator map_end = data.mPosOverrides.end();
+ while (map_iter != map_end)
+ {
+ if (include_overrides)
+ {
+ add_row_to_list(listp,
+ cell_params,
+ LLSD::Integer(count),
+ map_iter->first,
+ LLSD::Real(map_iter->second.mV[VX]),
+ LLSD::Real(map_iter->second.mV[VY]),
+ LLSD::Real(map_iter->second.mV[VZ]));
+ }
+ else
+ {
+ add_row_to_list(listp,
+ cell_params,
+ LLSD::Integer(count),
+ map_iter->first,
+ no_override_placeholder,
+ no_override_placeholder,
+ no_override_placeholder);
+ }
+ count++;
+ map_iter++;
+ }
+
+ std::set<std::string>::const_iterator set_iter = data.mModelsNoOverrides.begin();
+ std::set<std::string>::const_iterator set_end = data.mModelsNoOverrides.end();
+ while (set_iter != set_end)
+ {
+ add_row_to_list(listp,
+ cell_params,
+ LLSD::Integer(count),
+ *set_iter,
+ no_override_placeholder,
+ no_override_placeholder,
+ no_override_placeholder);
+ count++;
+ set_iter++;
+ }
+}
+
+void LLFloaterModelPreview::onJointListSelection()
+{
+ S32 display_lod = mModelPreview->mPreviewLOD;
+ LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
+ LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
+ LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
+ LLScrollListCtrl *joints_scale = panel->getChild<LLScrollListCtrl>("scale_overrides_list");
+ LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
+
+ joints_pos->deleteAllItems();
+ joints_scale->deleteAllItems();
+
+ LLScrollListItem *selected = joints_list->getFirstSelected();
+ if (selected)
+ {
+ std::string label = selected->getValue().asString();
+ LLJointOverrideData &data = mJointOverrides[display_lod][label];
+ bool upload_joint_positions = childGetValue("upload_joints").asBoolean();
+ populate_list_with_overrides(joints_pos, data, upload_joint_positions);
+
+ joint_pos_descr->setTextArg("[JOINT]", label);
+ mSelectedJointName = label;
+ }
+ else
+ {
+ // temporary value (shouldn't happen)
+ std::string label = "mPelvis";
+ joint_pos_descr->setTextArg("[JOINT]", label);
+ mSelectedJointName.clear();
+ }
+
+ // Note: We can make a version of renderBones() to highlight selected joint
+}
+
void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl)
{
// Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage
@@ -566,33 +666,6 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
}
//static
-void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)
-{
- LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
-
- if (!fp->mModelPreview)
- {
- return;
- }
-
- fp->mModelPreview->refresh();
-}
-
-//static
-void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata)
-{
- LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
-
- if (!fp->mModelPreview)
- {
- return;
- }
- fp->mModelPreview->refresh();
- fp->mModelPreview->resetPreviewTarget();
- fp->mModelPreview->clearBuffers();
-}
-
-//static
void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
@@ -622,6 +695,7 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda
void LLFloaterModelPreview::toggleGenarateNormals()
{
bool enabled = childGetValue("gen_normals").asBoolean();
+ mModelPreview->mViewOption["gen_normals"] = enabled;
childSetEnabled("crease_angle", enabled);
if(enabled) {
mModelPreview->generateNormals();
@@ -665,6 +739,27 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
}
}
+void LLFloaterModelPreview::draw3dPreview()
+{
+ gGL.color3f(1.f, 1.f, 1.f);
+
+ gGL.getTexUnit(0)->bind(mModelPreview);
+
+ gGL.begin( LLRender::QUADS );
+ {
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(mPreviewRect.mLeft+1, mPreviewRect.mTop-1);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(mPreviewRect.mLeft+1, mPreviewRect.mBottom+1);
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom+1);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
+ }
+ gGL.end();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+}
//-----------------------------------------------------------------------------
// draw()
@@ -711,36 +806,9 @@ void LLFloaterModelPreview::draw()
childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
- if (mModelPreview->lodsReady())
+ if (!isMinimized() && mModelPreview->lodsReady())
{
- gGL.color3f(1.f, 1.f, 1.f);
-
- gGL.getTexUnit(0)->bind(mModelPreview);
-
-
- LLView* preview_panel = getChild<LLView>("preview_panel");
-
- LLRect rect = preview_panel->getRect();
- if (rect != mPreviewRect)
- {
- mModelPreview->refresh();
- mPreviewRect = preview_panel->getRect();
- }
-
- gGL.begin( LLRender::QUADS );
- {
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1);
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom);
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1);
- }
- gGL.end();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ draw3dPreview();
}
}
@@ -839,7 +907,10 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
mModelPreview->zoom((F32)clicks * -0.2f);
mModelPreview->refresh();
}
-
+ else
+ {
+ LLFloaterModelUploadBase::handleScrollWheel(x, y, clicks);
+ }
return TRUE;
}
@@ -1100,7 +1171,8 @@ void LLFloaterModelPreview::initDecompControls()
float max = param[i].mDetails.mRange.mHigh.mFloat;
float delta = param[i].mDetails.mRange.mDelta.mFloat;
- if ("Cosine%" == name)
+ bool is_smooth_cb = ("Cosine%" == name);
+ if (is_smooth_cb)
{
createSmoothComboBox(combo_box, min, max);
}
@@ -1111,10 +1183,8 @@ void LLFloaterModelPreview::initDecompControls()
std::string label = llformat("%.1f", value);
combo_box->add(label, value, ADD_BOTTOM, true);
}
- combo_box->setValue(param[i].mDefault.mFloat);
-
}
-
+ combo_box->setValue(is_smooth_cb ? 0: param[i].mDefault.mFloat);
combo_box->setCommitCallback(onPhysicsParamCommit, (void*) &param[i]);
}
}
@@ -1186,7 +1256,7 @@ void LLFloaterModelPreview::initDecompControls()
//LL_INFOS() << "-----------------------------" << LL_ENDL;
}
}
-
+ mDefaultDecompParams = mDecompParams;
childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this);
}
@@ -1216,3092 +1286,280 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
}
//-----------------------------------------------------------------------------
-// LLModelPreview
+// addStringToLog()
//-----------------------------------------------------------------------------
-
-LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
-: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
-, mLodsQuery()
-, mLodsWithParsingError()
-, mPelvisZOffset( 0.0f )
-, mLegacyRigValid( false )
-, mRigValidJointUpload( false )
-, mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
-, mResetJoints( false )
-, mModelNoErrors( true )
-, mLastJointUpdate( false )
+//static
+void LLFloaterModelPreview::addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod)
{
- mNeedsUpdate = TRUE;
- mCameraDistance = 0.f;
- mCameraYaw = 0.f;
- mCameraPitch = 0.f;
- mCameraZoom = 1.f;
- mTextureName = 0;
- mPreviewLOD = 0;
- mModelLoader = NULL;
- mMaxTriangleLimit = 0;
- mDirty = false;
- mGenLOD = false;
- mLoading = false;
- mLoadState = LLModelLoader::STARTING;
- mGroup = 0;
- mLODFrozen = false;
- mBuildShareTolerance = 0.f;
- mBuildQueueMode = GLOD_QUEUE_GREEDY;
- mBuildBorderMode = GLOD_BORDER_UNLOCK;
- mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE;
-
- for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
+ if (sInstance && sInstance->hasString(message))
{
- mRequestedTriangleCount[i] = 0;
- mRequestedCreaseAngle[i] = -1.f;
- mRequestedLoDMode[i] = 0;
- mRequestedErrorThreshold[i] = 0.f;
- mRequestedBuildOperator[i] = 0;
- mRequestedQueueMode[i] = 0;
- mRequestedBorderMode[i] = 0;
- mRequestedShareTolerance[i] = 0.f;
- }
-
- mViewOption["show_textures"] = false;
-
- mFMP = fmp;
-
- mHasPivot = false;
- mModelPivot = LLVector3( 0.0f, 0.0f, 0.0f );
-
- glodInit();
-
- createPreviewAvatar();
-}
-
-LLModelPreview::~LLModelPreview()
+ std::string str;
+ switch (lod)
{
- // glod apparently has internal mem alignment issues that are angering
- // the heap-check code in windows, these should be hunted down in that
- // TP code, if possible
- //
- // kernel32.dll!HeapFree() + 0x14 bytes
- // msvcr100.dll!free(void * pBlock) Line 51 C
- // glod.dll!glodGetGroupParameteriv() + 0x119 bytes
- // glod.dll!glodShutdown() + 0x77 bytes
- //
- //glodShutdown();
- if(mModelLoader)
- {
- mModelLoader->shutdown();
- }
+ case LLModel::LOD_IMPOSTOR: str = "LOD0 "; break;
+ case LLModel::LOD_LOW: str = "LOD1 "; break;
+ case LLModel::LOD_MEDIUM: str = "LOD2 "; break;
+ case LLModel::LOD_PHYSICS: str = "PHYS "; break;
+ case LLModel::LOD_HIGH: str = "LOD3 "; break;
+ default: break;
}
-U32 LLModelPreview::calcResourceCost()
+ LLStringUtil::format_map_t args_msg;
+ LLSD::map_const_iterator iter = args.beginMap();
+ LLSD::map_const_iterator end = args.endMap();
+ for (; iter != end; ++iter)
{
- assert_main_thread();
-
- rebuildUploadData();
-
- //Upload skin is selected BUT check to see if the joints coming in from the asset were malformed.
- if ( mFMP && mFMP->childGetValue("upload_skin").asBoolean() )
- {
- bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean();
- if ( uploadingJointPositions && !isRigValidForJointPositionUpload() )
- {
- mFMP->childDisable("ok_btn");
+ args_msg[iter->first] = iter->second.asString();
}
+ str += sInstance->getString(message, args_msg);
+ sInstance->addStringToLogTab(str, flash);
}
-
- std::set<LLModel*> accounted;
- U32 num_points = 0;
- U32 num_hulls = 0;
-
- F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f;
- mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f;
-
- if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() )
- {
- // FIXME if preview avatar ever gets reused, this fake mesh ID stuff will fail.
- // see also call to addAttachmentPosOverride.
- LLUUID fake_mesh_id;
- fake_mesh_id.generate();
- getPreviewAvatar()->addPelvisFixup( mPelvisZOffset, fake_mesh_id );
}
- F32 streaming_cost = 0.f;
- F32 physics_cost = 0.f;
- for (U32 i = 0; i < mUploadData.size(); ++i)
+// static
+void LLFloaterModelPreview::addStringToLog(const std::string& str, bool flash)
{
- LLModelInstance& instance = mUploadData[i];
-
- if (accounted.find(instance.mModel) == accounted.end())
+ if (sInstance)
{
- accounted.insert(instance.mModel);
-
- LLModel::Decomposition& decomp =
- instance.mLOD[LLModel::LOD_PHYSICS] ?
- instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
- instance.mModel->mPhysics;
-
- //update instance skin info for each lods pelvisZoffset
- for ( int j=0; j<LLModel::NUM_LODS; ++j )
- {
- if ( instance.mLOD[j] )
- {
- instance.mLOD[j]->mSkinInfo.mPelvisOffset = mPelvisZOffset;
+ sInstance->addStringToLogTab(str, flash);
}
}
- std::stringstream ostr;
- LLSD ret = LLModel::writeModel(ostr,
- instance.mLOD[4],
- instance.mLOD[3],
- instance.mLOD[2],
- instance.mLOD[1],
- instance.mLOD[0],
- decomp,
- mFMP->childGetValue("upload_skin").asBoolean(),
- mFMP->childGetValue("upload_joints").asBoolean(),
- mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(),
- TRUE,
- FALSE,
- instance.mModel->mSubmodelID);
-
- num_hulls += decomp.mHull.size();
- for (U32 i = 0; i < decomp.mHull.size(); ++i)
+// static
+void LLFloaterModelPreview::addStringToLog(const std::ostringstream& strm, bool flash)
{
- num_points += decomp.mHull[i].size();
- }
-
- //calculate streaming cost
- LLMatrix4 transformation = instance.mTransform;
-
- LLVector3 position = LLVector3(0, 0, 0) * transformation;
-
- LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position;
- LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position;
- LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position;
- F32 x_length = x_transformed.normalize();
- F32 y_length = y_transformed.normalize();
- F32 z_length = z_transformed.normalize();
- LLVector3 scale = LLVector3(x_length, y_length, z_length);
-
- F32 radius = scale.length()*0.5f*debug_scale;
-
- LLMeshCostData costs;
- if (gMeshRepo.getCostData(ret, costs))
+ if (sInstance)
{
- streaming_cost += costs.getRadiusBasedStreamingCost(radius);
+ sInstance->addStringToLogTab(strm.str(), flash);
}
}
- }
-
- F32 scale = mFMP ? mFMP->childGetValue("import_scale").asReal()*2.f : 2.f;
-
- mDetailsSignal(mPreviewScale[0]*scale, mPreviewScale[1]*scale, mPreviewScale[2]*scale, streaming_cost, physics_cost);
-
- updateStatusMessages();
-
- return (U32) streaming_cost;
-}
-void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
+void LLFloaterModelPreview::clearAvatarTab()
{
- assert_main_thread();
- childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
- childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y));
- childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
-}
+ LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
+ LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
+ joints_list->deleteAllItems();
+ LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list");
+ joints_pos->deleteAllItems(); mSelectedJointName.clear();
-void LLFloaterModelPreview::setPreviewLOD(S32 lod)
+ for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
{
- if (mModelPreview)
- {
- mModelPreview->setPreviewLOD(lod);
+ mJointOverrides[i].clear();
}
-}
-
-
-void LLModelPreview::rebuildUploadData()
-{
- assert_main_thread();
-
- mUploadData.clear();
- mTextureSet.clear();
- //fill uploaddata instance vectors from scene data
+ LLTextBox *joint_total_descr = panel->getChild<LLTextBox>("conflicts_description");
+ joint_total_descr->setTextArg("[CONFLICTS]", llformat("%d", 0));
+ joint_total_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", 0));
- std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString();
- LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
-
- F32 scale = scale_spinner->getValue().asReal();
-
- LLMatrix4 scale_mat;
- scale_mat.initScale(LLVector3(scale, scale, scale));
-
- F32 max_scale = 0.f;
-
- BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
- BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
-
- for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
- { //for each transform in scene
- LLMatrix4 mat = iter->first;
-
- // compute position
- LLVector3 position = LLVector3(0, 0, 0) * mat;
-
- // compute scale
- LLVector3 x_transformed = LLVector3(1, 0, 0) * mat - position;
- LLVector3 y_transformed = LLVector3(0, 1, 0) * mat - position;
- LLVector3 z_transformed = LLVector3(0, 0, 1) * mat - position;
- F32 x_length = x_transformed.normalize();
- F32 y_length = y_transformed.normalize();
- F32 z_length = z_transformed.normalize();
-
- max_scale = llmax(llmax(llmax(max_scale, x_length), y_length), z_length);
-
- mat *= scale_mat;
-
- for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();)
- { //for each instance with said transform applied
- LLModelInstance instance = *model_iter++;
-
- LLModel* base_model = instance.mModel;
-
- if (base_model && !requested_name.empty())
- {
- base_model->mRequestedLabel = requested_name;
+ LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
+ joint_pos_descr->setTextArg("[JOINT]", std::string("mPelvis")); // Might be better to hide it
}
- for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--)
+void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
{
- LLModel* lod_model = NULL;
- if (!legacyMatching)
+ S32 display_lod = mModelPreview->mPreviewLOD;
+ if (mModelPreview->mModel[display_lod].empty())
{
- // Fill LOD slots by finding matching meshes by label with name extensions
- // in the appropriate scene for each LOD. This fixes all kinds of issues
- // where the indexed method below fails in spectacular fashion.
- // If you don't take the time to name your LOD and PHYS meshes
- // with the name of their corresponding mesh in the HIGH LOD,
- // then the indexed method will be attempted below.
-
- LLMatrix4 transform;
-
- std::string name_to_match = instance.mLabel;
- llassert(!name_to_match.empty());
-
- int extensionLOD;
- if (i != LLModel::LOD_PHYSICS || mModel[LLModel::LOD_PHYSICS].empty())
- {
- extensionLOD = i;
- }
- else
- {
- //Physics can be inherited from other LODs or loaded, so we need to adjust what extension we are searching for
- extensionLOD = mPhysicsSearchLOD;
+ mSelectedJointName.clear();
+ return;
}
- std::string toAdd;
- switch (extensionLOD)
+ // Joints will be listed as long as they are listed in mAlternateBindMatrix
+ // even if they are for some reason identical to defaults.
+ // Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't.
+ if (mJointOverrides[display_lod].empty())
{
- case LLModel::LOD_IMPOSTOR: toAdd = "_LOD0"; break;
- case LLModel::LOD_LOW: toAdd = "_LOD1"; break;
- case LLModel::LOD_MEDIUM: toAdd = "_LOD2"; break;
- case LLModel::LOD_PHYSICS: toAdd = "_PHYS"; break;
- case LLModel::LOD_HIGH: break;
- }
-
- if (name_to_match.find(toAdd) == -1)
+ // populate map
+ for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].end(); ++iter)
{
- name_to_match += toAdd;
- }
-
- FindModel(mScene[i], name_to_match, lod_model, transform);
-
- if (!lod_model && i != LLModel::LOD_PHYSICS)
+ for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
{
- if (importerDebug)
+ LLModelInstance& instance = *model_iter;
+ LLModel* model = instance.mModel;
+ const LLMeshSkinInfo *skin = &model->mSkinInfo;
+ U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);
+ U32 bind_count = highlight_overrides ? skin->mAlternateBindMatrix.size() : 0; // simply do not include overrides if data is not needed
+ if (bind_count > 0 && bind_count != joint_count)
{
- LL_INFOS() << "Search of" << name_to_match << " in LOD" << i << " list failed. Searching for alternative among LOD lists." << LL_ENDL;
+ std::ostringstream out;
+ out << "Invalid joint overrides for model " << model->getName();
+ out << ". Amount of joints " << joint_count;
+ out << ", is different from amount of overrides " << bind_count;
+ LL_INFOS() << out.str() << LL_ENDL;
+ addStringToLog(out.str(), true);
+ // Disable overrides for this model
+ bind_count = 0;
}
-
- int searchLOD = (i > LLModel::LOD_HIGH) ? LLModel::LOD_HIGH : i;
- while ((searchLOD <= LLModel::LOD_HIGH) && !lod_model)
+ if (bind_count > 0)
{
- std::string name_to_match = instance.mLabel;
- llassert(!name_to_match.empty());
-
- std::string toAdd;
- switch (searchLOD)
+ for (U32 j = 0; j < joint_count; ++j)
{
- case LLModel::LOD_IMPOSTOR: toAdd = "_LOD0"; break;
- case LLModel::LOD_LOW: toAdd = "_LOD1"; break;
- case LLModel::LOD_MEDIUM: toAdd = "_LOD2"; break;
- case LLModel::LOD_PHYSICS: toAdd = "_PHYS"; break;
- case LLModel::LOD_HIGH: break;
- }
+ const LLVector3& joint_pos = skin->mAlternateBindMatrix[j].getTranslation();
+ LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
- if (name_to_match.find(toAdd) == -1)
+ LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
+ if (pJoint)
{
- name_to_match += toAdd;
- }
-
- // See if we can find an appropriately named model in LOD 'searchLOD'
- //
- FindModel(mScene[searchLOD], name_to_match, lod_model, transform);
- searchLOD++;
- }
- }
- }
- else
+ // see how voavatar uses aboveJointPosThreshold
+ if (pJoint->aboveJointPosThreshold(joint_pos))
{
- // Use old method of index-based association
- U32 idx = 0;
- for (idx = 0; idx < mBaseModel.size(); ++idx)
+ // valid override
+ if (data.mPosOverrides.size() > 0
+ && (data.mPosOverrides.begin()->second - joint_pos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET))
{
- // find reference instance for this model
- if (mBaseModel[idx] == base_model)
- {
- if (importerDebug)
- {
- LL_INFOS() << "Attempting to use model index " << idx << " for LOD " << i << " of " << instance.mLabel << LL_ENDL;
+ // File contains multiple meshes with conflicting joint offsets
+ // preview may be incorrect, upload result might wary (depends onto
+ // mesh_id that hasn't been generated yet).
+ data.mHasConflicts = true;
}
- break;
- }
- }
-
- // If the model list for the current LOD includes that index...
- //
- if (mModel[i].size() > idx)
- {
- // Assign that index from the model list for our LOD as the LOD model for this instance
- //
- lod_model = mModel[i][idx];
- if (importerDebug)
- {
- LL_INFOS() << "Indexed match of model index " << idx << " at LOD " << i << " to model named " << lod_model->mLabel << LL_ENDL;
- }
- }
- else if (importerDebug)
- {
- LL_INFOS() << "List of models does not include index " << idx << LL_ENDL;
- }
- }
-
- if (lod_model)
- {
- if (importerDebug)
- {
- if (i == LLModel::LOD_PHYSICS)
- {
- LL_INFOS() << "Assigning collision for " << instance.mLabel << " to match " << lod_model->mLabel << LL_ENDL;
+ data.mPosOverrides[model->getName()] = joint_pos;
}
else
{
- LL_INFOS() << "Assigning LOD" << i << " for " << instance.mLabel << " to found match " << lod_model->mLabel << LL_ENDL;
- }
+ // default value, it won't be accounted for by avatar
+ data.mModelsNoOverrides.insert(model->getName());
}
- instance.mLOD[i] = lod_model;
- }
- else
- {
- if (i < LLModel::LOD_HIGH && !lodsReady())
- {
- // assign a placeholder from previous LOD until lod generation is complete.
- // Note: we might need to assign it regardless of conditions like named search does, to prevent crashes.
- instance.mLOD[i] = instance.mLOD[i + 1];
- }
- if (importerDebug)
- {
- LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL;
}
}
}
-
- LLModel* high_lod_model = instance.mLOD[LLModel::LOD_HIGH];
- if (!high_lod_model)
- {
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- }
else
{
- for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
+ for (U32 j = 0; j < joint_count; ++j)
{
- int refFaceCnt = 0;
- int modelFaceCnt = 0;
- llassert(instance.mLOD[i]);
- if (instance.mLOD[i] && !instance.mLOD[i]->matchMaterialOrder(high_lod_model, refFaceCnt, modelFaceCnt ) )
- {
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- }
- }
- LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP;
- bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean();
- if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0)
- {
- LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix);
- LLQuaternion identity;
- if (!bind_rot.isEqualEps(identity,0.01))
- {
- LL_WARNS() << "non-identity bind shape rot. mat is " << high_lod_model->mSkinInfo.mBindShapeMatrix
- << " bind_rot " << bind_rot << LL_ENDL;
- setLoadState( LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION );
+ LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
+ data.mModelsNoOverrides.insert(model->getName());
}
}
}
- instance.mTransform = mat;
- mUploadData.push_back(instance);
- }
- }
-
- for (U32 lod = 0; lod < LLModel::NUM_LODS-1; lod++)
- {
- // Search for models that are not included into upload data
- // If we found any, that means something we loaded is not a sub-model.
- for (U32 model_ind = 0; model_ind < mModel[lod].size(); ++model_ind)
- {
- bool found_model = false;
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
- if (instance.mLOD[lod] == mModel[lod][model_ind])
- {
- found_model = true;
- break;
- }
- }
- if (!found_model && mModel[lod][model_ind] && !mModel[lod][model_ind]->mSubmodelID)
- {
- if (importerDebug)
- {
- LL_INFOS() << "Model " << mModel[lod][model_ind]->mLabel << " was not used - mismatching lod models." << LL_ENDL;
- }
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- }
- }
- }
-
- F32 max_import_scale = (DEFAULT_MAX_PRIM_SCALE-0.1f)/max_scale;
-
- F32 max_axis = llmax(mPreviewScale.mV[0], mPreviewScale.mV[1]);
- max_axis = llmax(max_axis, mPreviewScale.mV[2]);
- max_axis *= 2.f;
-
- //clamp scale so that total imported model bounding box is smaller than 240m on a side
- max_import_scale = llmin(max_import_scale, 240.f/max_axis);
-
- scale_spinner->setMaxValue(max_import_scale);
-
- if (max_import_scale < scale)
- {
- scale_spinner->setValue(max_import_scale);
- }
-
-}
-
-void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)
-{
- if (!mLODFile[LLModel::LOD_HIGH].empty())
- {
- std::string filename = mLODFile[LLModel::LOD_HIGH];
- std::string slm_filename;
-
- if (LLModelLoader::getSLMFilename(filename, slm_filename))
- {
- saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position);
- }
- }
-}
-
-void LLModelPreview::saveUploadData(const std::string& filename,
- bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)
-{
-
- std::set<LLPointer<LLModel> > meshes;
- std::map<LLModel*, std::string> mesh_binary;
-
- LLModel::hull empty_hull;
-
- LLSD data;
-
- data["version"] = SLM_SUPPORTED_VERSION;
- if (!mBaseModel.empty())
- {
- data["name"] = mBaseModel[0]->getName();
- }
-
- S32 mesh_id = 0;
-
- //build list of unique models and initialize local id
- for (U32 i = 0; i < mUploadData.size(); ++i)
- {
- LLModelInstance& instance = mUploadData[i];
-
- if (meshes.find(instance.mModel) == meshes.end())
- {
- instance.mModel->mLocalID = mesh_id++;
- meshes.insert(instance.mModel);
-
- std::stringstream str;
- LLModel::Decomposition& decomp =
- instance.mLOD[LLModel::LOD_PHYSICS].notNull() ?
- instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
- instance.mModel->mPhysics;
-
- LLModel::writeModel(str,
- instance.mLOD[LLModel::LOD_PHYSICS],
- instance.mLOD[LLModel::LOD_HIGH],
- instance.mLOD[LLModel::LOD_MEDIUM],
- instance.mLOD[LLModel::LOD_LOW],
- instance.mLOD[LLModel::LOD_IMPOSTOR],
- decomp,
- save_skinweights,
- save_joint_positions,
- lock_scale_if_joint_position,
- FALSE, TRUE, instance.mModel->mSubmodelID);
-
- data["mesh"][instance.mModel->mLocalID] = str.str();
- }
-
- data["instance"][i] = instance.asLLSD();
- }
-
- llofstream out(filename.c_str(), std::ios_base::out | std::ios_base::binary);
- LLSDSerialize::toBinary(data, out);
- out.flush();
- out.close();
-}
-
-void LLModelPreview::clearModel(S32 lod)
-{
- if (lod < 0 || lod > LLModel::LOD_PHYSICS)
- {
- return;
- }
-
- mVertexBuffer[lod].clear();
- mModel[lod].clear();
- mScene[lod].clear();
-}
-
-void LLModelPreview::getJointAliases( JointMap& joint_map)
-{
- // Get all standard skeleton joints from the preview avatar.
- LLVOAvatar *av = getPreviewAvatar();
-
- //Joint names and aliases come from avatar_skeleton.xml
-
- joint_map = av->getJointAliases();
-
- std::vector<std::string> cv_names, attach_names;
- av->getSortedJointNames(1, cv_names);
- av->getSortedJointNames(2, attach_names);
- for (std::vector<std::string>::iterator it = cv_names.begin(); it != cv_names.end(); ++it)
- {
- joint_map[*it] = *it;
- }
- for (std::vector<std::string>::iterator it = attach_names.begin(); it != attach_names.end(); ++it)
- {
- joint_map[*it] = *it;
- }
-}
-
-void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm)
-{
- assert_main_thread();
-
- LLMutexLock lock(this);
-
- if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::NUM_LODS - 1)
- {
- LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL;
- assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS);
- return;
- }
-
- // This triggers if you bring up the file picker and then hit CANCEL.
- // Just use the previous model (if any) and ignore that you brought up
- // the file picker.
-
- if (filename.empty())
- {
- if (mBaseModel.empty())
- {
- // this is the initial file picking. Close the whole floater
- // if we don't have a base model to show for high LOD.
- mFMP->closeFloater(false);
}
- mLoading = false;
- return;
}
- if (mModelLoader)
- {
- LL_WARNS() << "Incompleted model load operation pending." << LL_ENDL;
- return;
- }
-
- mLODFile[lod] = filename;
+ LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
+ LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
- if (lod == LLModel::LOD_HIGH)
+ if (joints_list->isEmpty())
{
- clearGLODGroup();
- }
+ // Populate table
std::map<std::string, std::string> joint_alias_map;
- getJointAliases(joint_alias_map);
+ mModelPreview->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"));
-
- if (force_disable_slm)
+ S32 conflicts = 0;
+ joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin();
+ joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end();
+ while (joint_iter != joint_end)
{
- mModelLoader->mTrySLM = false;
- }
- else
- {
- // For MAINT-6647, we have set force_disable_slm to true,
- // which means this code path will never be taken. Trying to
- // re-use SLM files has never worked properly; in particular,
- // it tends to force the UI into strange checkbox options
- // which cannot be altered.
+ const std::string& listName = joint_iter->first;
- //only try to load from slm if viewer is configured to do so and this is the
- //initial model load (not an LoD or physics shape)
- mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty();
- }
- mModelLoader->start();
+ LLScrollListItem::Params item_params;
+ item_params.value(listName);
- mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file"));
-
- setPreviewLOD(lod);
-
- if ( getLoadState() >= LLModelLoader::ERROR_PARSING )
+ LLScrollListCell::Params cell_params;
+ cell_params.font = LLFontGL::getFontSansSerif();
+ cell_params.value = listName;
+ if (joint_alias_map.find(listName) == joint_alias_map.end())
{
- mFMP->childDisable("ok_btn");
- mFMP->childDisable( "calculate_btn" );
+ // Missing names
+ cell_params.color = LLColor4::red;
}
-
- if (lod == mPreviewLOD)
+ if (joint_iter->second.mHasConflicts)
{
- mFMP->childSetValue("lod_file_" + lod_name[lod], mLODFile[lod]);
+ // Conflicts
+ cell_params.color = LLColor4::orange;
+ conflicts++;
}
- else if (lod == LLModel::LOD_PHYSICS)
+ if (highlight_overrides && joint_iter->second.mPosOverrides.size() > 0)
{
- mFMP->childSetValue("physics_file", mLODFile[lod]);
+ cell_params.font.style = "BOLD";
}
- mFMP->openFloater();
-}
+ item_params.columns.add(cell_params);
-void LLModelPreview::setPhysicsFromLOD(S32 lod)
-{
- assert_main_thread();
-
- if (lod >= 0 && lod <= 3)
- {
- mPhysicsSearchLOD = lod;
- mModel[LLModel::LOD_PHYSICS] = mModel[lod];
- mScene[LLModel::LOD_PHYSICS] = mScene[lod];
- mLODFile[LLModel::LOD_PHYSICS].clear();
- mFMP->childSetValue("physics_file", mLODFile[LLModel::LOD_PHYSICS]);
- mVertexBuffer[LLModel::LOD_PHYSICS].clear();
- rebuildUploadData();
- refresh();
- updateStatusMessages();
+ joints_list->addRow(item_params, ADD_BOTTOM);
+ joint_iter++;
}
-}
-
-void LLModelPreview::clearIncompatible(S32 lod)
+ joints_list->selectFirstItem();
+ LLScrollListItem *selected = joints_list->getFirstSelected();
+ if (selected)
{
- //Don't discard models if specified model is the physic rep
- if ( lod == LLModel::LOD_PHYSICS )
- {
- return;
+ mSelectedJointName = selected->getValue().asString();
}
- // 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]);
- for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
- { //clear out any entries that aren't compatible with this model
- if (i != lod)
- {
- if (countRootModels(mModel[i]) != lod_size)
- {
- mModel[i].clear();
- mScene[i].clear();
- mVertexBuffer[i].clear();
-
- if (i == LLModel::LOD_HIGH)
- {
- mBaseModel = mModel[lod];
- clearGLODGroup();
- mBaseScene = mScene[lod];
- mVertexBuffer[5].clear();
- }
- }
+ LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description");
+ joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts));
+ joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size()));
}
}
-}
-void LLModelPreview::clearGLODGroup()
+//-----------------------------------------------------------------------------
+// addStringToLogTab()
+//-----------------------------------------------------------------------------
+void LLFloaterModelPreview::addStringToLogTab(const std::string& str, bool flash)
{
- if (mGroup)
- {
- for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter)
+ if (str.empty())
{
- glodDeleteObject(iter->second);
- stop_gloderror();
- }
- mObject.clear();
-
- glodDeleteGroup(mGroup);
- stop_gloderror();
- mGroup = 0;
- }
-}
-
-void LLModelPreview::loadModelCallback(S32 loaded_lod)
-{
- assert_main_thread();
-
- LLMutexLock lock(this);
- if (!mModelLoader)
- {
- mLoading = false ;
return;
}
- if(getLoadState() >= LLModelLoader::ERROR_PARSING)
- {
- mLoading = false ;
- mModelLoader = NULL;
- mLodsWithParsingError.push_back(loaded_lod);
- return ;
- }
-
- mLodsWithParsingError.erase(std::remove(mLodsWithParsingError.begin(), mLodsWithParsingError.end(), loaded_lod), mLodsWithParsingError.end());
- if(mLodsWithParsingError.empty())
- {
- mFMP->childEnable( "calculate_btn" );
- }
-
- // Copy determinations about rig so UI will reflect them
- //
- setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload());
- setLegacyRigValid(mModelLoader->isLegacyRigValid());
-
- mModelLoader->loadTextures() ;
-
- if (loaded_lod == -1)
- { //populate all LoDs from model loader scene
- mBaseModel.clear();
- mBaseScene.clear();
-
- bool skin_weights = false;
- bool joint_positions = false;
- bool lock_scale_if_joint_position = false;
-
- for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
- { //for each LoD
-
- //clear scene and model info
- mScene[lod].clear();
- mModel[lod].clear();
- mVertexBuffer[lod].clear();
-
- if (mModelLoader->mScene.begin()->second[0].mLOD[lod].notNull())
- { //if this LoD exists in the loaded scene
-
- //copy scene to current LoD
- mScene[lod] = mModelLoader->mScene;
-
- //touch up copied scene to look like current LoD
- for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter)
- {
- LLModelLoader::model_instance_list& list = iter->second;
-
- for (LLModelLoader::model_instance_list::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter)
- {
- //override displayed model with current LoD
- list_iter->mModel = list_iter->mLOD[lod];
-
- if (!list_iter->mModel)
- {
- continue;
- }
-
- //add current model to current LoD's model list (LLModel::mLocalID makes a good vector index)
- S32 idx = list_iter->mModel->mLocalID;
-
- if (mModel[lod].size() <= idx)
- { //stretch model list to fit model at given index
- mModel[lod].resize(idx+1);
- }
-
- mModel[lod][idx] = list_iter->mModel;
- if (!list_iter->mModel->mSkinWeights.empty())
- {
- skin_weights = true;
-
- if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty())
- {
- joint_positions = true;
- }
- if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition)
- {
- lock_scale_if_joint_position = true;
- }
- }
- }
- }
- }
- }
-
- if (mFMP)
- {
- LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP;
-
- if (skin_weights)
- { //enable uploading/previewing of skin weights if present in .slm file
- fmp->enableViewOption("show_skin_weight");
- mViewOption["show_skin_weight"] = true;
- fmp->childSetValue("upload_skin", true);
- }
-
- if (joint_positions)
- {
- fmp->enableViewOption("show_joint_positions");
- mViewOption["show_joint_positions"] = true;
- fmp->childSetValue("upload_joints", true);
- }
-
- if (lock_scale_if_joint_position)
- {
- fmp->enableViewOption("lock_scale_if_joint_position");
- mViewOption["lock_scale_if_joint_position"] = true;
- fmp->childSetValue("lock_scale_if_joint_position", true);
- }
- }
-
- //copy high lod to base scene for LoD generation
- mBaseScene = mScene[LLModel::LOD_HIGH];
- mBaseModel = mModel[LLModel::LOD_HIGH];
-
- mDirty = true;
- resetPreviewTarget();
- }
- else
- { //only replace given LoD
- mModel[loaded_lod] = mModelLoader->mModelList;
- mScene[loaded_lod] = mModelLoader->mScene;
- mVertexBuffer[loaded_lod].clear();
-
- setPreviewLOD(loaded_lod);
-
- if (loaded_lod == LLModel::LOD_HIGH)
- { //save a copy of the highest LOD for automatic LOD manipulation
- if (mBaseModel.empty())
- { //first time we've loaded a model, auto-gen LoD
- mGenLOD = true;
- }
-
- mBaseModel = mModel[loaded_lod];
- clearGLODGroup();
- mBaseScene = mScene[loaded_lod];
- mVertexBuffer[5].clear();
- }
- else
+ LLWString text = utf8str_to_wstring(str);
+ S32 add_text_len = text.length() + 1; // newline
+ S32 editor_max_len = mUploadLogText->getMaxTextLength();
+ if (add_text_len > editor_max_len)
{
- BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
- BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
- if (!legacyMatching)
- {
- if (!mBaseModel.empty())
- {
- BOOL name_based = FALSE;
- BOOL has_submodels = FALSE;
- for (U32 idx = 0; idx < mBaseModel.size(); ++idx)
- {
- if (mBaseModel[idx]->mSubmodelID)
- { // don't do index-based renaming when the base model has submodels
- has_submodels = TRUE;
- if (importerDebug)
- {
- LL_INFOS() << "High LOD has submodels" << LL_ENDL;
- }
- break;
- }
- }
-
- for (U32 idx = 0; idx < mModel[loaded_lod].size(); ++idx)
- {
- std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
-
- LLModel* found_model = NULL;
- LLMatrix4 transform;
- FindModel(mBaseScene, loaded_name, found_model, transform);
- if (found_model)
- { // don't rename correctly named models (even if they are placed in a wrong order)
- name_based = TRUE;
- }
-
- if (mModel[loaded_lod][idx]->mSubmodelID)
- { // don't rename the models when loaded LOD model has submodels
- has_submodels = TRUE;
- }
- }
-
- if (importerDebug)
- {
- LL_INFOS() << "Loaded LOD " << loaded_lod << ": correct names" << (name_based ? "" : "NOT ") << "found; submodels " << (has_submodels ? "" : "NOT ") << "found" << LL_ENDL;
- }
-
- if (!name_based && !has_submodels)
- { // replace the name of the model loaded for any non-HIGH LOD to match the others (MAINT-5601)
- // this actually works like "ImporterLegacyMatching" for this particular LOD
- for (U32 idx = 0; idx < mModel[loaded_lod].size() && idx < mBaseModel.size(); ++idx)
- {
- std::string name = mBaseModel[idx]->mLabel;
- std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
-
- if (loaded_name != name)
- {
- switch (loaded_lod)
- {
- case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
- case LLModel::LOD_LOW: name += "_LOD1"; break;
- case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
- case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
- case LLModel::LOD_HIGH: break;
- }
-
- if (importerDebug)
- {
- LL_WARNS() << "Loded model name " << mModel[loaded_lod][idx]->mLabel << " for LOD " << loaded_lod << " doesn't match the base model. Renaming to " << name << LL_ENDL;
- }
-
- mModel[loaded_lod][idx]->mLabel = name;
- }
- }
- }
- }
- }
- }
-
- clearIncompatible(loaded_lod);
-
- mDirty = true;
-
- if (loaded_lod == LLModel::LOD_HIGH)
- {
- resetPreviewTarget();
- }
- }
-
- mLoading = false;
- if (mFMP)
- {
- mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);
- if (!mBaseModel.empty())
- {
- const std::string& model_name = mBaseModel[0]->getName();
- LLLineEditor* description_form = mFMP->getChild<LLLineEditor>("description_form");
- if (description_form->getText().empty())
- {
- description_form->setText(model_name);
- }
- }
- }
- refresh();
-
- mModelLoadedSignal();
-
- mModelLoader = NULL;
-}
-
-void LLModelPreview::resetPreviewTarget()
-{
- if ( mModelLoader )
- {
- mPreviewTarget = (mModelLoader->mExtents[0] + mModelLoader->mExtents[1]) * 0.5f;
- mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f;
- }
-
- setPreviewTarget(mPreviewScale.magVec()*10.f);
-}
-
-void LLModelPreview::generateNormals()
-{
- assert_main_thread();
-
- S32 which_lod = mPreviewLOD;
-
- if (which_lod > 4 || which_lod < 0 ||
- mModel[which_lod].empty())
- {
return;
}
- F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal();
-
- mRequestedCreaseAngle[which_lod] = angle_cutoff;
-
- angle_cutoff *= DEG_TO_RAD;
-
- if (which_lod == 3 && !mBaseModel.empty())
+ // Make sure we have space for new string
+ S32 editor_text_len = mUploadLogText->getLength();
+ if (editor_max_len < (editor_text_len + add_text_len)
+ && mUploadLogText->getLineCount() <= 0)
{
- if(mBaseModelFacesCopy.empty())
- {
- mBaseModelFacesCopy.reserve(mBaseModel.size());
- for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it)
- {
- v_LLVolumeFace_t faces;
- (*it)->copyFacesTo(faces);
- mBaseModelFacesCopy.push_back(faces);
+ mUploadLogText->getTextBoundingRect();// forces a reflow() to fix line count
}
- }
-
- for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it)
+ while (editor_max_len < (editor_text_len + add_text_len))
{
- (*it)->generateNormals(angle_cutoff);
- }
-
- mVertexBuffer[5].clear();
- }
-
- bool perform_copy = mModelFacesCopy[which_lod].empty();
- if(perform_copy) {
- mModelFacesCopy[which_lod].reserve(mModel[which_lod].size());
- }
-
- for (LLModelLoader::model_list::iterator it = mModel[which_lod].begin(), itE = mModel[which_lod].end(); it != itE; ++it)
- {
- if(perform_copy)
- {
- v_LLVolumeFace_t faces;
- (*it)->copyFacesTo(faces);
- mModelFacesCopy[which_lod].push_back(faces);
- }
-
- (*it)->generateNormals(angle_cutoff);
- }
-
- mVertexBuffer[which_lod].clear();
- refresh();
- updateStatusMessages();
-}
-
-void LLModelPreview::restoreNormals()
-{
- S32 which_lod = mPreviewLOD;
-
- if (which_lod > 4 || which_lod < 0 ||
- mModel[which_lod].empty())
- {
- return;
- }
-
- if(!mBaseModelFacesCopy.empty())
- {
- llassert(mBaseModelFacesCopy.size() == mBaseModel.size());
-
- vv_LLVolumeFace_t::const_iterator itF = mBaseModelFacesCopy.begin();
- for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it, ++itF)
- {
- (*it)->copyFacesFrom((*itF));
- }
-
- mBaseModelFacesCopy.clear();
- }
-
- if(!mModelFacesCopy[which_lod].empty())
+ S32 shift = mUploadLogText->removeFirstLine();
+ if (shift > 0)
{
- vv_LLVolumeFace_t::const_iterator itF = mModelFacesCopy[which_lod].begin();
- for (LLModelLoader::model_list::iterator it = mModel[which_lod].begin(), itE = mModel[which_lod].end(); it != itE; ++it, ++itF)
- {
- (*it)->copyFacesFrom((*itF));
- }
-
- mModelFacesCopy[which_lod].clear();
- }
-
- mVertexBuffer[which_lod].clear();
- refresh();
- updateStatusMessages();
+ // removed a line
+ editor_text_len -= shift;
}
-
-void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit)
-{
- // Allow LoD from -1 to LLModel::LOD_PHYSICS
- if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1)
- {
- LL_WARNS() << "Invalid level of detail: " << which_lod << LL_ENDL;
- assert(which_lod >= -1 && which_lod < LLModel::NUM_LODS);
- return;
- }
-
- if (mBaseModel.empty())
- {
- return;
- }
-
- LLVertexBuffer::unbind();
-
- bool no_ff = LLGLSLShader::sNoFixedFunction;
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- LLGLSLShader::sNoFixedFunction = false;
-
- if (shader)
- {
- shader->unbind();
- }
-
- stop_gloderror();
- static U32 cur_name = 1;
-
- S32 limit = -1;
-
- U32 triangle_count = 0;
-
- U32 instanced_triangle_count = 0;
-
- //get the triangle count for the whole scene
- for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)
- {
- for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
- {
- LLModel* mdl = instance->mModel;
- if (mdl)
- {
- instanced_triangle_count += mdl->getNumTriangles();
- }
- }
- }
-
- //get the triangle count for the non-instanced set of models
- for (U32 i = 0; i < mBaseModel.size(); ++i)
- {
- triangle_count += mBaseModel[i]->getNumTriangles();
- }
-
- //get ratio of uninstanced triangles to instanced triangles
- F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count;
-
- U32 base_triangle_count = triangle_count;
-
- U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
-
- U32 lod_mode = 0;
-
- F32 lod_error_threshold = 0;
-
- // The LoD should be in range from Lowest to High
- if (which_lod > -1 && which_lod < NUM_LOD)
- {
- LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[which_lod]);
- if (iface)
- {
- lod_mode = iface->getFirstSelectedIndex();
- }
-
- lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal();
- }
-
- if (which_lod != -1)
- {
- mRequestedLoDMode[which_lod] = lod_mode;
- }
-
- if (lod_mode == 0)
- {
- lod_mode = GLOD_TRIANGLE_BUDGET;
-
- // The LoD should be in range from Lowest to High
- if (which_lod > -1 && which_lod < NUM_LOD)
- {
- limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
- //convert from "scene wide" to "non-instanced" triangle limit
- limit = (S32) ( (F32) limit*triangle_ratio );
- }
- }
else
{
- lod_mode = GLOD_ERROR_THRESHOLD;
- }
-
- bool object_dirty = false;
-
- if (mGroup == 0)
- {
- object_dirty = true;
- mGroup = cur_name++;
- glodNewGroup(mGroup);
- }
-
- if (object_dirty)
- {
- for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
- { //build GLOD objects for each model in base model list
- LLModel* mdl = *iter;
-
- if (mObject[mdl] != 0)
- {
- glodDeleteObject(mObject[mdl]);
- }
-
- mObject[mdl] = cur_name++;
-
- glodNewObject(mObject[mdl], mGroup, GLOD_DISCRETE);
- stop_gloderror();
-
- if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty())
- { //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation
- mVertexBuffer[5].clear();
- }
-
- if (mVertexBuffer[5].empty())
- {
- genBuffers(5, false);
- }
-
- U32 tri_count = 0;
- for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i)
- {
- LLVertexBuffer* buff = mVertexBuffer[5][mdl][i];
- buff->setBuffer(type_mask & buff->getTypeMask());
-
- U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();
- if (num_indices > 2)
- {
- glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, (U8*) mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f);
- }
- tri_count += num_indices/3;
- stop_gloderror();
- }
-
- glodBuildObject(mObject[mdl]);
- stop_gloderror();
- }
- }
-
-
- S32 start = LLModel::LOD_HIGH;
- S32 end = 0;
-
- if (which_lod != -1)
- {
- start = end = which_lod;
- }
-
- mMaxTriangleLimit = base_triangle_count;
-
- for (S32 lod = start; lod >= end; --lod)
- {
- if (which_lod == -1)
- {
- if (lod < start)
- {
- triangle_count /= decimation;
- }
- }
- else
- {
- if (enforce_tri_limit)
- {
- triangle_count = limit;
- }
- else
- {
- for (S32 j=LLModel::LOD_HIGH; j>which_lod; --j)
- {
- triangle_count /= decimation;
- }
- }
- }
-
- mModel[lod].clear();
- mModel[lod].resize(mBaseModel.size());
- mVertexBuffer[lod].clear();
-
- U32 actual_tris = 0;
- U32 actual_verts = 0;
- U32 submeshes = 0;
-
- mRequestedTriangleCount[lod] = (S32) ( (F32) triangle_count / triangle_ratio );
- mRequestedErrorThreshold[lod] = lod_error_threshold;
-
- glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
- stop_gloderror();
-
- glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
- stop_gloderror();
-
- glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
- stop_gloderror();
-
- if (lod_mode != GLOD_TRIANGLE_BUDGET)
- {
- glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, 0);
- }
- else
- {
- //SH-632: always add 1 to desired amount to avoid decimating below desired amount
- glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count+1);
- }
-
- stop_gloderror();
- glodAdaptGroup(mGroup);
- stop_gloderror();
-
- for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx)
- {
- LLModel* base = mBaseModel[mdl_idx];
-
- GLint patch_count = 0;
- glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count);
- stop_gloderror();
-
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f);
-
- std::string name = base->mLabel;
-
- switch (lod)
- {
- case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
- case LLModel::LOD_LOW: name += "_LOD1"; break;
- case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
- case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
- case LLModel::LOD_HIGH: break;
- }
-
- mModel[lod][mdl_idx]->mLabel = name;
- mModel[lod][mdl_idx]->mSubmodelID = base->mSubmodelID;
-
- GLint* sizes = new GLint[patch_count*2];
- glodGetObjectParameteriv(mObject[base], GLOD_PATCH_SIZES, sizes);
- stop_gloderror();
-
- GLint* names = new GLint[patch_count];
- glodGetObjectParameteriv(mObject[base], GLOD_PATCH_NAMES, names);
- stop_gloderror();
-
- mModel[lod][mdl_idx]->setNumVolumeFaces(patch_count);
-
- LLModel* target_model = mModel[lod][mdl_idx];
-
- for (GLint i = 0; i < patch_count; ++i)
- {
- type_mask = mVertexBuffer[5][base][i]->getTypeMask();
-
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
-
- if (sizes[i*2+1] > 0 && sizes[i*2] > 0)
- {
- if (!buff->allocateBuffer(sizes[i * 2 + 1], sizes[i * 2], true))
- {
- // Todo: find a way to stop preview in this case instead of crashing
- LL_ERRS() << "Failed buffer allocation during preview LOD generation."
- << " Vertices: " << sizes[i * 2 + 1]
- << " Indices: " << sizes[i * 2] << LL_ENDL;
- }
- buff->setBuffer(type_mask);
- glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer());
- stop_gloderror();
- }
- else
- {
- // This face was eliminated or we failed to allocate buffer,
- // attempt to create a dummy triangle (one vertex, 3 indices, all 0)
- buff->allocateBuffer(1, 3, true);
- memset((U8*) buff->getMappedData(), 0, buff->getSize());
- memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize());
- }
-
- buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
-
- LLStrider<LLVector3> pos;
- LLStrider<LLVector3> norm;
- LLStrider<LLVector2> tc;
- LLStrider<U16> index;
-
- buff->getVertexStrider(pos);
- if (type_mask & LLVertexBuffer::MAP_NORMAL)
- {
- buff->getNormalStrider(norm);
- }
- if (type_mask & LLVertexBuffer::MAP_TEXCOORD0)
- {
- buff->getTexCoord0Strider(tc);
- }
-
- buff->getIndexStrider(index);
-
- target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());
- actual_tris += buff->getNumIndices()/3;
- actual_verts += buff->getNumVerts();
- ++submeshes;
-
- if (!validate_face(target_model->getVolumeFace(names[i])))
- {
- LL_ERRS() << "Invalid face generated during LOD generation." << LL_ENDL;
- }
- }
-
- //blind copy skin weights and just take closest skin weight to point on
- //decimated mesh for now (auto-generating LODs with skin weights is still a bit
- //of an open problem).
- target_model->mPosition = base->mPosition;
- target_model->mSkinWeights = base->mSkinWeights;
- target_model->mSkinInfo = base->mSkinInfo;
- //copy material list
- target_model->mMaterialList = base->mMaterialList;
-
- if (!validate_model(target_model))
- {
- LL_ERRS() << "Invalid model generated when creating LODs" << LL_ENDL;
- }
-
- delete [] sizes;
- delete [] names;
- }
-
- //rebuild scene based on mBaseScene
- mScene[lod].clear();
- mScene[lod] = mBaseScene;
-
- for (U32 i = 0; i < mBaseModel.size(); ++i)
- {
- LLModel* mdl = mBaseModel[i];
- LLModel* target = mModel[lod][i];
- if (target)
- {
- for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter)
- {
- for (U32 j = 0; j < iter->second.size(); ++j)
- {
- if (iter->second[j].mModel == mdl)
- {
- iter->second[j].mModel = target;
- }
- }
- }
- }
- }
- }
-
- mResourceCost = calcResourceCost();
-
- LLVertexBuffer::unbind();
- LLGLSLShader::sNoFixedFunction = no_ff;
- if (shader)
- {
- shader->bind();
- }
-}
-
-void LLModelPreview::updateStatusMessages()
-{
- assert_main_thread();
-
- //triangle/vertex/submesh count for each mesh asset for each lod
- std::vector<S32> tris[LLModel::NUM_LODS];
- std::vector<S32> verts[LLModel::NUM_LODS];
- std::vector<S32> submeshes[LLModel::NUM_LODS];
-
- //total triangle/vertex/submesh count for each lod
- S32 total_tris[LLModel::NUM_LODS];
- S32 total_verts[LLModel::NUM_LODS];
- S32 total_submeshes[LLModel::NUM_LODS];
-
- for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
- {
- total_tris[i] = 0;
- total_verts[i] = 0;
- total_submeshes[i] = 0;
- }
-
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
-
- LLModel* model_high_lod = instance.mLOD[LLModel::LOD_HIGH];
- if (!model_high_lod)
- {
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- continue;
- }
-
- for (U32 i = 0; i < LLModel::NUM_LODS-1; i++)
- {
- LLModel* lod_model = instance.mLOD[i];
- if (!lod_model)
- {
- setLoadState( LLModelLoader::ERROR_MATERIALS );
- mFMP->childDisable( "calculate_btn" );
- }
- else
- {
- //for each model in the lod
- S32 cur_tris = 0;
- S32 cur_verts = 0;
- S32 cur_submeshes = lod_model->getNumVolumeFaces();
-
- for (S32 j = 0; j < cur_submeshes; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = lod_model->getVolumeFace(j);
- cur_tris += face.mNumIndices/3;
- cur_verts += face.mNumVertices;
- }
-
- std::string instance_name = instance.mLabel;
-
- BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
- if (importerDebug)
- {
- // Useful for debugging generalized complaints below about total submeshes which don't have enough
- // context to address exactly what needs to be fixed to move towards compliance with the rules.
- //
- LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Verts: " << cur_verts << LL_ENDL;
- LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Tris: " << cur_tris << LL_ENDL;
- LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Faces: " << cur_submeshes << LL_ENDL;
-
- LLModel::material_list::iterator mat_iter = lod_model->mMaterialList.begin();
- while (mat_iter != lod_model->mMaterialList.end())
- {
- LL_INFOS() << "Instance " << lod_model->mLabel << " LOD " << i << " Material " << *(mat_iter) << LL_ENDL;
- mat_iter++;
- }
- }
-
- //add this model to the lod total
- total_tris[i] += cur_tris;
- total_verts[i] += cur_verts;
- total_submeshes[i] += cur_submeshes;
-
- //store this model's counts to asset data
- tris[i].push_back(cur_tris);
- verts[i].push_back(cur_verts);
- submeshes[i].push_back(cur_submeshes);
- }
- }
- }
-
- if (mMaxTriangleLimit == 0)
- {
- mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
- }
-
- bool has_degenerate = false;
-
- {//check for degenerate triangles in physics mesh
- U32 lod = LLModel::LOD_PHYSICS;
- const LLVector4a scale(0.5f);
- for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
- { //for each model in the lod
- if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
- { //no decomp exists
- S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
- for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
- for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; )
- {
- U16 index_a = face.mIndices[k+0];
- U16 index_b = face.mIndices[k+1];
- U16 index_c = face.mIndices[k+2];
-
- LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
- LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
- LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
-
- if (ll_is_degenerate(v1,v2,v3))
- {
- has_degenerate = true;
- }
- else
- {
- k += 3;
- }
- }
- }
- }
- }
- }
-
- mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
-
- std::string mesh_status_na = mFMP->getString("mesh_status_na");
-
- S32 upload_status[LLModel::LOD_HIGH+1];
-
- mModelNoErrors = true;
-
- const U32 lod_high = LLModel::LOD_HIGH;
- U32 high_submodel_count = mModel[lod_high].size() - countRootModels(mModel[lod_high]);
-
- for (S32 lod = 0; lod <= lod_high; ++lod)
- {
- upload_status[lod] = 0;
-
- std::string message = "mesh_status_good";
-
- if (total_tris[lod] > 0)
- {
- mFMP->childSetValue(lod_triangles_name[lod], llformat("%d", total_tris[lod]));
- mFMP->childSetValue(lod_vertices_name[lod], llformat("%d", total_verts[lod]));
- }
- else
- {
- if (lod == lod_high)
- {
- upload_status[lod] = 2;
- message = "mesh_status_missing_lod";
- }
- else
- {
- for (S32 i = lod-1; i >= 0; --i)
- {
- if (total_tris[i] > 0)
- {
- upload_status[lod] = 2;
- message = "mesh_status_missing_lod";
- }
- }
- }
-
- mFMP->childSetValue(lod_triangles_name[lod], mesh_status_na);
- mFMP->childSetValue(lod_vertices_name[lod], mesh_status_na);
- }
-
- if (lod != lod_high)
- {
- if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high])
- { //number of submeshes is different
- message = "mesh_status_submesh_mismatch";
- upload_status[lod] = 2;
- }
- else if (mModel[lod].size() - countRootModels(mModel[lod]) != high_submodel_count)
- {//number of submodels is different, not all faces are matched correctly.
- message = "mesh_status_submesh_mismatch";
- upload_status[lod] = 2;
- // Note: Submodels in instance were loaded from higher LOD and as result face count
- // returns same value and total_submeshes[lod] is identical to high_lod one.
- }
- else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())
- { //number of meshes is different
- message = "mesh_status_mesh_mismatch";
- upload_status[lod] = 2;
- }
- else if (!verts[lod].empty())
- {
- S32 sum_verts_higher_lod = 0;
- S32 sum_verts_this_lod = 0;
- for (U32 i = 0; i < verts[lod].size(); ++i)
- {
- sum_verts_higher_lod += ((i < verts[lod+1].size()) ? verts[lod+1][i] : 0);
- sum_verts_this_lod += verts[lod][i];
- }
-
- if ((sum_verts_higher_lod > 0) &&
- (sum_verts_this_lod > sum_verts_higher_lod))
- {
- //too many vertices in this lod
- message = "mesh_status_too_many_vertices";
- upload_status[lod] = 1;
- }
- }
- }
-
- LLIconCtrl* icon = mFMP->getChild<LLIconCtrl>(lod_icon_name[lod]);
- LLUIImagePtr img = LLUI::getUIImage(lod_status_image[upload_status[lod]]);
- icon->setVisible(true);
- icon->setImage(img);
-
- if (upload_status[lod] >= 2)
- {
- mModelNoErrors = false;
- }
-
- if (lod == mPreviewLOD)
- {
- mFMP->childSetValue("lod_status_message_text", mFMP->getString(message));
- icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon");
- icon->setImage(img);
- }
-
- updateLodControls(lod);
- }
-
-
- //warn if hulls have more than 256 points in them
- BOOL physExceededVertexLimit = FALSE;
- for (U32 i = 0; mModelNoErrors && i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
- {
- LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i];
-
- if (mdl)
- {
- for (U32 j = 0; j < mdl->mPhysics.mHull.size(); ++j)
- {
- if (mdl->mPhysics.mHull[j].size() > 256)
- {
- physExceededVertexLimit = TRUE;
- LL_INFOS() << "Physical model " << mdl->mLabel << " exceeds vertex per hull limitations." << LL_ENDL;
+ //nothing to remove?
+ LL_WARNS() << "Failed to clear log lines" << LL_ENDL;
break;
}
}
- }
- }
- mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
- LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
- physStatusIcon->setVisible(physExceededVertexLimit);
- if (physExceededVertexLimit)
- {
- mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
- LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
- physStatusIcon->setImage(img);
- }
-
- if (getLoadState() >= LLModelLoader::ERROR_PARSING)
- {
- mModelNoErrors = false;
- LL_INFOS() << "Loader returned errors, model can't be uploaded" << LL_ENDL;
- }
-
- bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean();
- bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean();
-
- if ( uploadingSkin )
- {
- if ( uploadingJointPositions && !isRigValidForJointPositionUpload() )
- {
- mModelNoErrors = false;
- LL_INFOS() << "Invalid rig, there might be issues with uploading Joint positions" << LL_ENDL;
- }
- }
- if(mModelNoErrors && mModelLoader)
- {
- if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
- {
- // Some textures are still loading, prevent upload until they are done
- mModelNoErrors = false;
- }
- }
-
- // Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics
- // current use of has_degenerate won't block upload permanently - later checks will restore the button
- if (!mModelNoErrors || has_degenerate)
- {
- mFMP->childDisable("ok_btn");
- }
-
- if (mModelNoErrors && mLodsWithParsingError.empty())
- {
- mFMP->childEnable("calculate_btn");
- }
- else
- {
- mFMP->childDisable("calculate_btn");
- }
-
- //add up physics triangles etc
- S32 phys_tris = 0;
- S32 phys_hulls = 0;
- S32 phys_points = 0;
-
- //get the triangle count for the whole scene
- for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter)
- {
- for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
- {
- LLModel* model = instance->mModel;
- if (model)
- {
- S32 cur_submeshes = model->getNumVolumeFaces();
-
- LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
-
- if (!decomp.empty())
- {
- phys_hulls += decomp.size();
- for (U32 i = 0; i < decomp.size(); ++i)
- {
- phys_points += decomp[i].size();
- }
- }
- else
- { //choose physics shape OR decomposition, can't use both
- for (S32 j = 0; j < cur_submeshes; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = model->getVolumeFace(j);
- phys_tris += face.mNumIndices/3;
- }
- }
- }
- }
- }
-
- if (phys_tris > 0)
- {
- mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", llformat("%d", phys_tris));
- }
- else
- {
- mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", mesh_status_na);
- }
-
- if (phys_hulls > 0)
- {
- mFMP->childSetTextArg("physics_hulls", "[HULLS]", llformat("%d", phys_hulls));
- mFMP->childSetTextArg("physics_points", "[POINTS]", llformat("%d", phys_points));
- }
- else
- {
- mFMP->childSetTextArg("physics_hulls", "[HULLS]", mesh_status_na);
- mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);
- }
-
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
- if (fmp)
- {
- if (phys_tris > 0 || phys_hulls > 0)
- {
- if (!fmp->isViewOptionEnabled("show_physics"))
- {
- fmp->enableViewOption("show_physics");
- mViewOption["show_physics"] = true;
- fmp->childSetValue("show_physics", true);
- }
- }
- else
- {
- fmp->disableViewOption("show_physics");
- mViewOption["show_physics"] = false;
- fmp->childSetValue("show_physics", false);
-
- }
-
- //bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean();
-
- //fmp->childSetEnabled("physics_optimize", !use_hull);
-
- bool enable = (phys_tris > 0 || phys_hulls > 0) && fmp->mCurRequest.empty();
- //enable = enable && !use_hull && fmp->childGetValue("physics_optimize").asBoolean();
-
- //enable/disable "analysis" UI
- LLPanel* panel = fmp->getChild<LLPanel>("physics analysis");
- LLView* child = panel->getFirstChild();
- while (child)
- {
- child->setEnabled(enable);
- child = panel->findNextSibling(child);
- }
-
- enable = phys_hulls > 0 && fmp->mCurRequest.empty();
- //enable/disable "simplification" UI
- panel = fmp->getChild<LLPanel>("physics simplification");
- child = panel->getFirstChild();
- while (child)
- {
- child->setEnabled(enable);
- child = panel->findNextSibling(child);
- }
-
- if (fmp->mCurRequest.empty())
- {
- fmp->childSetVisible("Simplify", true);
- fmp->childSetVisible("simplify_cancel", false);
- fmp->childSetVisible("Decompose", true);
- fmp->childSetVisible("decompose_cancel", false);
-
- if (phys_hulls > 0)
- {
- fmp->childEnable("Simplify");
- }
-
- if (phys_tris || phys_hulls > 0)
- {
- fmp->childEnable("Decompose");
- }
- }
- else
- {
- fmp->childEnable("simplify_cancel");
- fmp->childEnable("decompose_cancel");
- }
- }
-
-
- LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo");
- S32 which_mode = 0;
- S32 file_mode = 1;
- if (iface)
- {
- which_mode = iface->getFirstSelectedIndex();
- file_mode = iface->getItemCount() - 1;
- }
-
- if (which_mode == file_mode)
- {
- mFMP->childEnable("physics_file");
- mFMP->childEnable("physics_browse");
- }
- else
- {
- mFMP->childDisable("physics_file");
- mFMP->childDisable("physics_browse");
- }
-
- LLSpinCtrl* crease = mFMP->getChild<LLSpinCtrl>("crease_angle");
-
- if (mRequestedCreaseAngle[mPreviewLOD] == -1.f)
- {
- mFMP->childSetColor("crease_label", LLColor4::grey);
- crease->forceSetValue(75.f);
- }
- else
- {
- mFMP->childSetColor("crease_label", LLColor4::white);
- crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]);
- }
-
- mModelUpdatedSignal(true);
-
-}
-
-void LLModelPreview::updateLodControls(S32 lod)
-{
- if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::LOD_HIGH)
- {
- LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL;
- assert(lod >= LLModel::LOD_IMPOSTOR && lod <= LLModel::LOD_HIGH);
- return;
- }
-
- const char* lod_controls[] =
- {
- "lod_mode_",
- "lod_triangle_limit_",
- "lod_error_threshold_"
- };
- const U32 num_lod_controls = sizeof(lod_controls)/sizeof(char*);
-
- const char* file_controls[] =
- {
- "lod_browse_",
- "lod_file_",
- };
- const U32 num_file_controls = sizeof(file_controls)/sizeof(char*);
-
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
- if (!fmp) return;
-
- LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[lod]);
- if (!lod_combo) return;
-
- S32 lod_mode = lod_combo->getCurrentIndex();
- if (lod_mode == LOD_FROM_FILE) // LoD from file
- {
- fmp->mLODMode[lod] = 0;
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->childSetVisible(file_controls[i] + lod_name[lod], true);
- }
-
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->childSetVisible(lod_controls[i] + lod_name[lod], false);
- }
- }
- else if (lod_mode == USE_LOD_ABOVE) // use LoD above
- {
- fmp->mLODMode[lod] = 2;
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->childSetVisible(file_controls[i] + lod_name[lod], false);
- }
-
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->childSetVisible(lod_controls[i] + lod_name[lod], false);
- }
-
- if (lod < LLModel::LOD_HIGH)
- {
- mModel[lod] = mModel[lod + 1];
- mScene[lod] = mScene[lod + 1];
- mVertexBuffer[lod].clear();
-
- // Also update lower LoD
- if (lod > LLModel::LOD_IMPOSTOR)
- {
- updateLodControls(lod - 1);
- }
- }
- }
- else // auto generate, the default case for all LoDs except High
- {
- fmp->mLODMode[lod] = 1;
-
- //don't actually regenerate lod when refreshing UI
- mLODFrozen = true;
-
- for (U32 i = 0; i < num_file_controls; ++i)
- {
- mFMP->getChildView(file_controls[i] + lod_name[lod])->setVisible(false);
- }
-
- for (U32 i = 0; i < num_lod_controls; ++i)
- {
- mFMP->getChildView(lod_controls[i] + lod_name[lod])->setVisible(true);
- }
-
-
- LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod]);
- LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod]);
-
- limit->setMaxValue(mMaxTriangleLimit);
- limit->forceSetValue(mRequestedTriangleCount[lod]);
-
- threshold->forceSetValue(mRequestedErrorThreshold[lod]);
-
- mFMP->getChild<LLComboBox>("lod_mode_" + lod_name[lod])->selectNthItem(mRequestedLoDMode[lod]);
-
- if (mRequestedLoDMode[lod] == 0)
- {
- limit->setVisible(true);
- threshold->setVisible(false);
-
- limit->setMaxValue(mMaxTriangleLimit);
- limit->setIncrement(mMaxTriangleLimit/32);
- }
- else
- {
- limit->setVisible(false);
- threshold->setVisible(true);
- }
-
- mLODFrozen = false;
- }
-}
-
-void LLModelPreview::setPreviewTarget(F32 distance)
-{
- mCameraDistance = distance;
- mCameraZoom = 1.f;
- mCameraPitch = 0.f;
- mCameraYaw = 0.f;
- mCameraOffset.clearVec();
-}
-
-void LLModelPreview::clearBuffers()
-{
- for (U32 i = 0; i < 6; i++)
- {
- mVertexBuffer[i].clear();
- }
-}
-
-void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
-{
- U32 tri_count = 0;
- U32 vertex_count = 0;
- U32 mesh_count = 0;
-
-
- LLModelLoader::model_list* model = NULL;
-
- if (lod < 0 || lod > 4)
- {
- model = &mBaseModel;
- lod = 5;
- }
- else
- {
- model = &(mModel[lod]);
- }
-
- if (!mVertexBuffer[lod].empty())
- {
- mVertexBuffer[lod].clear();
- }
-
- mVertexBuffer[lod].clear();
-
- LLModelLoader::model_list::iterator base_iter = mBaseModel.begin();
-
- for (LLModelLoader::model_list::iterator iter = model->begin(); iter != model->end(); ++iter)
- {
- LLModel* mdl = *iter;
- if (!mdl)
- {
- continue;
- }
-
- LLModel* base_mdl = *base_iter;
- base_iter++;
-
- S32 num_faces = mdl->getNumVolumeFaces();
- for (S32 i = 0; i < num_faces; ++i)
- {
- const LLVolumeFace &vf = mdl->getVolumeFace(i);
- U32 num_vertices = vf.mNumVertices;
- U32 num_indices = vf.mNumIndices;
-
- if (!num_vertices || ! num_indices)
- {
- continue;
- }
-
- LLVertexBuffer* vb = NULL;
-
- bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
-
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 ;
-
- if (skinned)
- {
- mask |= LLVertexBuffer::MAP_WEIGHT4;
- }
-
- vb = new LLVertexBuffer(mask, 0);
-
- if (!vb->allocateBuffer(num_vertices, num_indices, TRUE))
- {
- // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview
- LL_WARNS() << "Failed to allocate Vertex Buffer for model preview "
- << num_vertices << " vertices and "
- << num_indices << " indices" << LL_ENDL;
- }
-
- LLStrider<LLVector3> vertex_strider;
- LLStrider<LLVector3> normal_strider;
- LLStrider<LLVector2> tc_strider;
- LLStrider<U16> index_strider;
- LLStrider<LLVector4> weights_strider;
-
- vb->getVertexStrider(vertex_strider);
- vb->getIndexStrider(index_strider);
-
- if (skinned)
- {
- vb->getWeight4Strider(weights_strider);
- }
-
- LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32));
-
- if (vf.mTexCoords)
- {
- vb->getTexCoord0Strider(tc_strider);
- S32 tex_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, tex_size);
- }
-
- if (vf.mNormals)
- {
- vb->getNormalStrider(normal_strider);
- LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32));
- }
-
- if (skinned)
- {
- for (U32 i = 0; i < num_vertices; i++)
- {
- //find closest weight to vf.mVertices[i].mPosition
- LLVector3 pos(vf.mPositions[i].getF32ptr());
-
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
- llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
-
- LLVector4 w(0,0,0,0);
-
- for (U32 i = 0; i < weight_list.size(); ++i)
- {
- F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f);
- F32 joint = (F32) weight_list[i].mJointIdx;
- w.mV[i] = joint + wght;
- llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values
- //should not cause floating point precision issues.
- }
-
- *(weights_strider++) = w;
- }
- }
-
- // build indices
- for (U32 i = 0; i < num_indices; i++)
- {
- *(index_strider++) = vf.mIndices[i];
- }
-
- mVertexBuffer[lod][mdl].push_back(vb);
-
- vertex_count += num_vertices;
- tri_count += num_indices/3;
- ++mesh_count;
-
- }
- }
-}
-
-void LLModelPreview::update()
-{
- if (mGenLOD)
- {
- bool subscribe_for_generation = mLodsQuery.empty();
- mGenLOD = false;
- mDirty = true;
- mLodsQuery.clear();
-
- for (S32 lod = LLModel::LOD_HIGH; lod >= 0; --lod)
- {
- // adding all lods into query for generation
- mLodsQuery.push_back(lod);
- }
-
- if (subscribe_for_generation)
- {
- doOnIdleRepeating(lodQueryCallback);
- }
- }
-
- if (mDirty && mLodsQuery.empty())
- {
- mDirty = false;
- mResourceCost = calcResourceCost();
- refresh();
- updateStatusMessages();
- }
-}
-
-//-----------------------------------------------------------------------------
-// createPreviewAvatar
-//-----------------------------------------------------------------------------
-void LLModelPreview::createPreviewAvatar( void )
-{
- mPreviewAvatar = (LLVOAvatar*)gObjectList.createObjectViewer( LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR );
- if ( mPreviewAvatar )
- {
- mPreviewAvatar->createDrawable( &gPipeline );
- mPreviewAvatar->mSpecialRenderMode = 1;
- mPreviewAvatar->startMotion( ANIM_AGENT_STAND );
- mPreviewAvatar->hideSkirt();
- }
- else
- {
- LL_INFOS() << "Failed to create preview avatar for upload model window" << LL_ENDL;
- }
-}
+ mUploadLogText->appendText(str, true);
-//static
-U32 LLModelPreview::countRootModels(LLModelLoader::model_list models)
-{
- U32 root_models = 0;
- model_list::iterator model_iter = models.begin();
- while (model_iter != models.end())
+ if (flash)
{
- LLModel* mdl = *model_iter;
- if (mdl && mdl->mSubmodelID == 0)
+ LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
+ if (mTabContainer->getCurrentPanel() != panel)
{
- root_models++;
+ mTabContainer->setTabPanelFlashing(panel, true);
}
- model_iter++;
- }
- return root_models;
-}
-
-void LLModelPreview::loadedCallback(
- LLModelLoader::scene& scene,
- LLModelLoader::model_list& model_list,
- S32 lod,
- void* opaque)
-{
- LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
- if (pPreview && !LLModelPreview::sIgnoreLoadedCallback)
- {
- pPreview->loadModelCallback(lod);
- }
-}
-
-void LLModelPreview::stateChangedCallback(U32 state,void* opaque)
-{
- LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
- if (pPreview)
- {
- pPreview->setLoadState(state);
- }
-}
-
-LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque)
-{
- LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
- if (pPreview)
- {
- return pPreview->getPreviewAvatar()->getJoint(str);
}
- return NULL;
-}
-
-U32 LLModelPreview::loadTextures(LLImportMaterial& material,void* opaque)
-{
- (void)opaque;
-
- if (material.mDiffuseMapFilename.size())
- {
- material.mOpaqueData = new LLPointer< LLViewerFetchedTexture >;
- LLPointer< LLViewerFetchedTexture >& tex = (*reinterpret_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData));
-
- tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
- tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE);
- tex->forceToSaveRawImage(0, F32_MAX);
- material.setDiffuseMap(tex->getID()); // record tex ID
- return 1;
}
- material.mOpaqueData = NULL;
- return 0;
-}
-
-void LLModelPreview::addEmptyFace( LLModel* pTarget )
-{
- U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
-
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
-
- buff->allocateBuffer(1, 3, true);
- memset( (U8*) buff->getMappedData(), 0, buff->getSize() );
- memset( (U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize() );
-
- buff->validateRange( 0, buff->getNumVerts()-1, buff->getNumIndices(), 0 );
-
- LLStrider<LLVector3> pos;
- LLStrider<LLVector3> norm;
- LLStrider<LLVector2> tc;
- LLStrider<U16> index;
-
- buff->getVertexStrider(pos);
-
- if ( type_mask & LLVertexBuffer::MAP_NORMAL )
- {
- buff->getNormalStrider(norm);
- }
- if ( type_mask & LLVertexBuffer::MAP_TEXCOORD0 )
- {
- buff->getTexCoord0Strider(tc);
- }
-
- buff->getIndexStrider(index);
-
- //resize face array
- int faceCnt = pTarget->getNumVolumeFaces();
- pTarget->setNumVolumeFaces( faceCnt+1 );
- pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
-
-}
-
-//-----------------------------------------------------------------------------
-// render()
-//-----------------------------------------------------------------------------
-BOOL LLModelPreview::render()
+void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
{
assert_main_thread();
-
- LLMutexLock lock(this);
- mNeedsUpdate = FALSE;
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- bool edges = mViewOption["show_edges"];
- bool joint_positions = mViewOption["show_joint_positions"];
- bool skin_weight = mViewOption["show_skin_weight"];
- bool textures = mViewOption["show_textures"];
- bool physics = mViewOption["show_physics"];
-
- S32 width = getWidth();
- S32 height = getHeight();
-
- LLGLSUIDefault def;
- LLGLDisable no_blend(GL_BLEND);
- LLGLEnable cull(GL_CULL_FACE);
- LLGLDepthTest depth(GL_TRUE);
- LLGLDisable fog(GL_FOG);
-
- {
- if (use_shaders)
- {
- gUIProgram.bind();
- }
- //clear background to blue
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- gGL.color4f(0.169f, 0.169f, 0.169f, 1.f);
-
- gl_rect_2d_simple( width, height );
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- if (use_shaders)
- {
- gUIProgram.unbind();
- }
- }
-
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
-
- bool has_skin_weights = false;
- bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
- bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
-
- if ( upload_joints != mLastJointUpdate )
- {
- mLastJointUpdate = upload_joints;
- }
-
- for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
- {
- for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
- {
- LLModelInstance& instance = *model_iter;
- LLModel* model = instance.mModel;
- model->mPelvisOffset = mPelvisZOffset;
- if (!model->mSkinWeights.empty())
- {
- has_skin_weights = true;
- }
+ childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
+ childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y));
+ childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
}
- }
- if (has_skin_weights && lodsReady())
- { //model has skin weights, enable view options for skin weights and joint positions
- if (fmp && isLegacyRigValid() )
- {
- fmp->enableViewOption("show_skin_weight");
- fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
- mFMP->childEnable("upload_skin");
- mFMP->childSetValue("show_skin_weight", skin_weight);
- }
- }
- else
- {
- mFMP->childDisable("upload_skin");
- if (fmp)
+void LLFloaterModelPreview::setPreviewLOD(S32 lod)
{
- mViewOption["show_skin_weight"] = false;
- fmp->disableViewOption("show_skin_weight");
- fmp->disableViewOption("show_joint_positions");
-
- skin_weight = false;
- mFMP->childSetValue("show_skin_weight", false);
- fmp->setViewOptionEnabled("show_skin_weight", skin_weight);
- }
- }
-
- if (upload_skin && !has_skin_weights)
- { //can't upload skin weights if model has no skin weights
- mFMP->childSetValue("upload_skin", false);
- upload_skin = false;
- }
-
- if (!upload_skin && upload_joints)
- { //can't upload joints if not uploading skin weights
- mFMP->childSetValue("upload_joints", false);
- upload_joints = false;
- }
-
- if (upload_skin && upload_joints)
- {
- mFMP->childEnable("lock_scale_if_joint_position");
- }
- else
- {
- mFMP->childDisable("lock_scale_if_joint_position");
- mFMP->childSetValue("lock_scale_if_joint_position", false);
- }
-
- //Only enable joint offsets if it passed the earlier critiquing
- if ( isRigValidForJointPositionUpload() )
- {
- mFMP->childSetEnabled("upload_joints", upload_skin);
- }
-
- F32 explode = mFMP->childGetValue("physics_explode").asReal();
-
- glClear(GL_DEPTH_BUFFER_BIT);
-
- LLRect preview_rect;
-
- preview_rect = mFMP->getChildView("preview_panel")->getRect();
-
- F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight();
-
- LLViewerCamera::getInstance()->setAspect(aspect);
-
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
-
- LLVector3 offset = mCameraOffset;
- LLVector3 target_pos = mPreviewTarget+offset;
-
- F32 z_near = 0.001f;
- F32 z_far = mCameraDistance*10.0f+mPreviewScale.magVec()+mCameraOffset.magVec();
-
- if (skin_weight)
- {
- target_pos = getPreviewAvatar()->getPositionAgent();
- z_near = 0.01f;
- z_far = 1024.f;
- mCameraDistance = 16.f;
-
- //render avatar previews every frame
- refresh();
- }
-
- if (use_shaders)
- {
- gObjectPreviewProgram.bind();
- }
-
- gGL.loadIdentity();
- gPipeline.enableLightsPreview();
-
- LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
- LLQuaternion(mCameraYaw, LLVector3::z_axis);
-
- LLQuaternion av_rot = camera_rot;
- LLViewerCamera::getInstance()->setOriginAndLookAt(
- target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
- LLVector3::z_axis, // up
- target_pos); // point of interest
-
-
- z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
-
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far);
-
- stop_glerror();
-
- gGL.pushMatrix();
- const F32 BRIGHTNESS = 0.9f;
- gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
-
- const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
-
- LLGLEnable normalize(GL_NORMALIZE);
-
- if (!mBaseModel.empty() && mVertexBuffer[5].empty())
- {
- genBuffers(-1, skin_weight);
- //genBuffers(3);
- //genLODs();
- }
-
- if (!mModel[mPreviewLOD].empty())
+ if (mModelPreview)
{
- mFMP->childEnable("reset_btn");
-
- bool regen = mVertexBuffer[mPreviewLOD].empty();
- if (!regen)
- {
- const std::vector<LLPointer<LLVertexBuffer> >& vb_vec = mVertexBuffer[mPreviewLOD].begin()->second;
- if (!vb_vec.empty())
- {
- const LLVertexBuffer* buff = vb_vec[0];
- regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight;
- }
- else
- {
- LL_INFOS() << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
- regen = TRUE;
- }
- }
-
- if (regen)
- {
- genBuffers(mPreviewLOD, skin_weight);
- }
-
- if (!skin_weight)
- {
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
-
- LLModel* model = instance.mLOD[mPreviewLOD];
-
- if (!model)
- {
- continue;
- }
-
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
-
- gGL.multMatrix((GLfloat*) mat.mMatrix);
-
-
- U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
- for (U32 i = 0; i < num_models; ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
-
- if (textures)
- {
- int materialCnt = instance.mModel->mMaterialList.size();
- if ( i < materialCnt )
- {
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
-
- gGL.diffuseColor4fv(material.mDiffuseColor.mV);
-
- // Find the tex for this material, bind it, and add it to our set
- //
- LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
- if (tex)
- {
- mTextureSet.insert(tex);
- }
- }
- }
- else
- {
- gGL.diffuseColor4f(1,1,1,1);
- }
-
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
-
- if (edges)
- {
- glLineWidth(3.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
- }
- }
- gGL.popMatrix();
- }
-
- if (physics)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
-
- for (U32 i = 0; i < 2; i++)
- {
- if (i == 0)
- { //depth only pass
- gGL.setColorMask(false, false);
- }
- else
- {
- gGL.setColorMask(true, true);
- }
-
- //enable alpha blending on second pass but not first pass
- LLGLState blend(GL_BLEND, i);
-
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
-
- LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
-
- if (!model)
- {
- continue;
- }
-
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
-
- gGL.multMatrix((GLfloat*) mat.mMatrix);
-
-
- bool render_mesh = true;
-
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
-
- LLModel::Decomposition& physics = model->mPhysics;
-
- if (!physics.mHull.empty())
- {
- render_mesh = false;
-
- if (physics.mMesh.empty())
- { //build vertex buffer for physics mesh
- gMeshRepo.buildPhysicsMesh(physics);
- }
-
- if (!physics.mMesh.empty())
- { //render hull instead of mesh
- for (U32 i = 0; i < physics.mMesh.size(); ++i)
- {
- if (explode > 0.f)
- {
- gGL.pushMatrix();
-
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
-
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
-
- static std::vector<LLColor4U> hull_colors;
-
- if (i+1 >= hull_colors.size())
- {
- hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
- }
-
- gGL.diffuseColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
-
- if (explode > 0.f)
- {
- gGL.popMatrix();
- }
- }
- }
- }
- }
-
- if (render_mesh)
- {
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
- U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
- for (U32 i = 0; i < num_models; ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f);
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
-
- gGL.diffuseColor3f(1.f, 1.f, 0.f);
-
- glLineWidth(2.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
- }
- }
-
- gGL.popMatrix();
- }
-
- glLineWidth(3.f);
- glPointSize(8.f);
- gPipeline.enableLightsFullbright(LLColor4::white);
- //show degenerate triangles
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- LLGLDisable cull(GL_CULL_FACE);
- gGL.diffuseColor4f(1.f,0.f,0.f,1.f);
- const LLVector4a scale(0.5f);
-
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
- {
- LLModelInstance& instance = *iter;
-
- LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
-
- if (!model)
- {
- continue;
- }
-
- gGL.pushMatrix();
- LLMatrix4 mat = instance.mTransform;
-
- gGL.multMatrix((GLfloat*) mat.mMatrix);
-
-
- LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
- if (decomp)
- {
- LLMutexLock(decomp->mMutex);
-
- LLModel::Decomposition& physics = model->mPhysics;
-
- if (physics.mHull.empty())
- {
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
- for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
-
- LLStrider<LLVector3> pos_strider;
- buffer->getVertexStrider(pos_strider, 0);
- LLVector4a* pos = (LLVector4a*) pos_strider.get();
-
- LLStrider<U16> idx;
- buffer->getIndexStrider(idx, 0);
-
- for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
- {
- LLVector4a v1; v1.setMul(pos[*idx++], scale);
- LLVector4a v2; v2.setMul(pos[*idx++], scale);
- LLVector4a v3; v3.setMul(pos[*idx++], scale);
-
- if (ll_is_degenerate(v1,v2,v3))
- {
- buffer->draw(LLRender::LINE_LOOP, 3, i);
- buffer->draw(LLRender::POINTS, 3, i);
- }
- }
+ mModelPreview->setPreviewLOD(lod);
}
}
- }
-
- gGL.popMatrix();
- }
- glLineWidth(1.f);
- glPointSize(1.f);
- gPipeline.enableLightsPreview();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
- }
- }
- else
- {
- target_pos = getPreviewAvatar()->getPositionAgent();
-
- LLViewerCamera::getInstance()->setOriginAndLookAt(
- target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
- LLVector3::z_axis, // up
- target_pos); // point of interest
-
- for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
- {
- for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
- {
- LLModelInstance& instance = *model_iter;
- LLModel* model = instance.mModel;
-
- if (!model->mSkinWeights.empty())
- {
- for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)
- {
- LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
-
- const LLVolumeFace& face = model->getVolumeFace(i);
-
- LLStrider<LLVector3> position;
- buffer->getVertexStrider(position);
-
- LLStrider<LLVector4> weight;
- buffer->getWeight4Strider(weight);
-
- //quick 'n dirty software vertex skinning
-
- //build matrix palette
-
- LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- const LLMeshSkinInfo *skin = &model->mSkinInfo;
- U32 count = LLSkinningUtil::getMeshJointCount(skin);
- LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count,
- skin, getPreviewAvatar());
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
- U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
- F32 *wptr = weight[j].mV;
- LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
-
- //VECTORIZE THIS
- LLVector4a& v = face.mPositions[j];
-
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
-
- position[j][0] = dst[0];
- position[j][1] = dst[1];
- position[j][2] = dst[2];
- }
-
- llassert(model->mMaterialList.size() > i);
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
- gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Find the tex for this material, bind it, and add it to our set
- //
- LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
- if (tex)
- {
- mTextureSet.insert(tex);
- }
-
- buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
- gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
-
- if (edges)
- {
- glLineWidth(3.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glLineWidth(1.f);
- }
- }
- }
- }
- }
-
- if (joint_positions)
- {
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- gDebugProgram.bind();
- }
- getPreviewAvatar()->renderCollisionVolumes();
- getPreviewAvatar()->renderBones();
- if (shader)
- {
- shader->bind();
- }
- }
-
- }
- }
-
- if (use_shaders)
- {
- gObjectPreviewProgram.unbind();
- }
-
- gGL.popMatrix();
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// refresh()
-//-----------------------------------------------------------------------------
-void LLModelPreview::refresh()
-{
- mNeedsUpdate = TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// rotate()
-//-----------------------------------------------------------------------------
-void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
-{
- mCameraYaw = mCameraYaw + yaw_radians;
-
- mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
-}
-
-//-----------------------------------------------------------------------------
-// zoom()
-//-----------------------------------------------------------------------------
-void LLModelPreview::zoom(F32 zoom_amt)
-{
- F32 new_zoom = mCameraZoom+zoom_amt;
-
- mCameraZoom = llclamp(new_zoom, 1.f, 10.f);
-}
-
-void LLModelPreview::pan(F32 right, F32 up)
-{
- mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
- mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
-}
-
-void LLModelPreview::setPreviewLOD(S32 lod)
-{
- lod = llclamp(lod, 0, (S32) LLModel::LOD_HIGH);
-
- if (lod != mPreviewLOD)
- {
- mPreviewLOD = lod;
-
- LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo");
- combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
- mFMP->childSetValue("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
-
- LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
- combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
-
- LLComboBox* combo_box3 = mFMP->getChild<LLComboBox>("preview_lod_combo3");
- combo_box3->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
-
- LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor");
- LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor");
-
- for (S32 i = 0; i <= LLModel::LOD_HIGH; ++i)
- {
- const LLColor4& color = (i == lod) ? highlight_color : normal_color;
-
- mFMP->childSetColor(lod_status_name[i], color);
- mFMP->childSetColor(lod_label_name[i], color);
- mFMP->childSetColor(lod_triangles_name[i], color);
- mFMP->childSetColor(lod_vertices_name[i], color);
- }
- }
- refresh();
- updateStatusMessages();
-}
void LLFloaterModelPreview::onBrowseLOD(S32 lod)
{
@@ -4315,12 +1573,16 @@ void LLFloaterModelPreview::onReset(void* user_data)
{
assert_main_thread();
+
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data;
fmp->childDisable("reset_btn");
+ fmp->clearLogTab();
+ fmp->clearAvatarTab();
LLModelPreview* mp = fmp->mModelPreview;
std::string filename = mp->mLODFile[LLModel::LOD_HIGH];
fmp->resetDisplayOptions();
+ fmp->resetUploadOptions();
//reset model preview
fmp->initModelPreview();
@@ -4334,6 +1596,7 @@ void LLFloaterModelPreview::onUpload(void* user_data)
assert_main_thread();
LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data;
+ mp->clearLogTab();
mp->mUploadBtn->setEnabled(false);
@@ -4362,70 +1625,36 @@ void LLFloaterModelPreview::refresh()
sInstance->mModelPreview->mDirty = true;
}
-//static
-void LLModelPreview::textureLoadedCallback(
- BOOL success,
- LLViewerFetchedTexture *src_vi,
- LLImageRaw* src,
- LLImageRaw* src_aux,
- S32 discard_level,
- BOOL final,
- void* userdata )
+LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
{
- LLModelPreview* preview = (LLModelPreview*) userdata;
- preview->refresh();
+ mStage = stage;
+ mContinue = 1;
+ mModel = mdl;
+ mDecompID = &mdl->mDecompID;
+ mParams = sInstance->mDecompParams;
- if(final && preview->mModelLoader)
- {
- if(preview->mModelLoader->mNumOfFetchingTextures > 0)
- {
- preview->mModelLoader->mNumOfFetchingTextures-- ;
- }
- }
+ //copy out positions and indices
+ assignData(mdl) ;
}
-// static
-bool LLModelPreview::lodQueryCallback()
+void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
- // not the best solution, but model preview belongs to floater
- // so it is an easy way to check that preview still exists.
- LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
- if (fmp && fmp->mModelPreview)
+ if (lod == LLModel::LOD_PHYSICS)
{
- LLModelPreview* preview = fmp->mModelPreview;
- if (preview->mLodsQuery.size() > 0)
+ LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
+ if (lod_combo)
{
- S32 lod = preview->mLodsQuery.back();
- preview->mLodsQuery.pop_back();
- preview->genLODs(lod);
-
- // return false to continue cycle
- return false;
+ lod_combo->setCurrentByIndex(5);
}
}
- // nothing to process
- return true;
-}
-
-void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
+ else
{
- if (!mLODFrozen)
+ LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
+ if (lod_combo)
{
- genLODs(lod, 3, enforce_tri_limit);
- refresh();
+ lod_combo->setCurrentByIndex(0);
}
}
-
-LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
-{
- mStage = stage;
- mContinue = 1;
- mModel = mdl;
- mDecompID = &mdl->mDecompID;
- mParams = sInstance->mDecompParams;
-
- //copy out positions and indices
- assignData(mdl) ;
}
void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
@@ -4439,6 +1668,12 @@ void LLFloaterModelPreview::toggleCalculateButton()
toggleCalculateButton(true);
}
+void LLFloaterModelPreview::modelUpdated(bool calculate_visible)
+{
+ mModelPhysicsFee.clear();
+ toggleCalculateButton(calculate_visible);
+}
+
void LLFloaterModelPreview::toggleCalculateButton(bool visible)
{
mCalculateBtn->setVisible(visible);
@@ -4464,12 +1699,19 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
childSetTextArg("download_weight", "[ST]", tbd);
childSetTextArg("server_weight", "[SIM]", tbd);
childSetTextArg("physics_weight", "[PH]", tbd);
- childSetTextArg("upload_fee", "[FEE]", tbd);
- childSetTextArg("price_breakdown", "[STREAMING]", tbd);
- childSetTextArg("price_breakdown", "[PHYSICS]", tbd);
- childSetTextArg("price_breakdown", "[INSTANCES]", tbd);
- childSetTextArg("price_breakdown", "[TEXTURES]", tbd);
- childSetTextArg("price_breakdown", "[MODEL]", tbd);
+ if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap())
+ {
+ childSetTextArg("upload_fee", "[FEE]", tbd);
+ }
+ std::string dashes = hasString("--") ? getString("--") : "--";
+ childSetTextArg("price_breakdown", "[STREAMING]", dashes);
+ childSetTextArg("price_breakdown", "[PHYSICS]", dashes);
+ childSetTextArg("price_breakdown", "[INSTANCES]", dashes);
+ childSetTextArg("price_breakdown", "[TEXTURES]", dashes);
+ childSetTextArg("price_breakdown", "[MODEL]", dashes);
+ childSetTextArg("physics_breakdown", "[PCH]", dashes);
+ childSetTextArg("physics_breakdown", "[PM]", dashes);
+ childSetTextArg("physics_breakdown", "[PHU]", dashes);
}
}
@@ -4496,6 +1738,44 @@ void LLFloaterModelPreview::resetDisplayOptions()
}
}
+void LLFloaterModelPreview::resetUploadOptions()
+{
+ childSetValue("import_scale", 1);
+ childSetValue("pelvis_offset", 0);
+ childSetValue("physics_explode", 0);
+ childSetValue("physics_file", "");
+ childSetVisible("Retain%", false);
+ childSetVisible("Retain%_label", false);
+ childSetVisible("Detail Scale", true);
+ childSetVisible("Detail Scale label", true);
+
+ getChild<LLComboBox>("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE);
+ for (S32 lod = 0; lod < NUM_LOD - 1; ++lod)
+ {
+ getChild<LLComboBox>("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE);
+ childSetValue("lod_file_" + lod_name[lod], "");
+ }
+
+ for(auto& p : mDefaultDecompParams)
+ {
+ std::string ctrl_name(p.first);
+ LLUICtrl* ctrl = getChild<LLUICtrl>(ctrl_name);
+ if (ctrl)
+ {
+ ctrl->setValue(p.second);
+ }
+ }
+ getChild<LLComboBox>("physics_lod_combo")->setCurrentByIndex(0);
+ getChild<LLComboBox>("Cosine%")->setCurrentByIndex(0);
+}
+
+void LLFloaterModelPreview::clearLogTab()
+{
+ mUploadLogText->clear();
+ LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
+ mTabContainer->setTabPanelFlashing(panel, false);
+}
+
void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
{
mModelPhysicsFee = result;
@@ -4519,15 +1799,40 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger()));
childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger()));
childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger()));
+
+ childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal()));
+ childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal()));
+ childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal()));
+ childSetTextArg("streaming_breakdown", "[STR_TOTAL]", llformat("%d", result["streaming_cost"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_HIGH]", llformat("%d", result["streaming_params"]["high_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger()));
+ childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger()));
+
childSetVisible("upload_fee", true);
childSetVisible("price_breakdown", true);
mUploadBtn->setEnabled(isModelUploadAllowed());
}
-void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason)
+void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason, const LLSD& result)
{
- LL_WARNS() << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << LL_ENDL;
+ std::ostringstream out;
+ out << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status;
+ out << " : " << reason << ")";
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, true));
+
+ if (result.has("upload_price"))
+ {
+ mModelPhysicsFee = result;
+ childSetTextArg("upload_fee", "[FEE]", llformat("%d", result["upload_price"].asInteger()));
+ childSetVisible("upload_fee", true);
+ }
+ else
+ {
+ mModelPhysicsFee.clear();
+ }
}
/*virtual*/
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index edc90d1695..8a01b0c307 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -28,36 +28,26 @@
#define LL_LLFLOATERMODELPREVIEW_H
#include "llfloaternamedesc.h"
-
-#include "lldynamictexture.h"
-#include "llquaternion.h"
-#include "llmeshrepository.h"
-#include "llmodel.h"
-#include "llthread.h"
-#include "llviewermenufile.h"
#include "llfloatermodeluploadbase.h"
-
-#include "lldaeloader.h"
+#include "llmeshrepository.h"
class LLComboBox;
class LLJoint;
-class LLViewerJointMesh;
-class LLVOAvatar;
-class LLTextBox;
-class LLVertexBuffer;
+class LLMeshFilePicker;
class LLModelPreview;
-class LLFloaterModelPreview;
-class DAE;
-class daeElement;
-class domProfile_COMMON;
-class domInstance_geometry;
-class domNode;
-class domTranslate;
-class domController;
-class domSkin;
-class domMesh;
-class LLMenuButton;
-class LLToggleableMenu;
+class LLTabContainer;
+class LLViewerTextEditor;
+
+
+class LLJointOverrideData
+{
+public:
+ LLJointOverrideData() : mHasConflicts(false) {};
+ std::map<std::string, LLVector3> mPosOverrides; // models with overrides
+ std::set<std::string> mModelsNoOverrides; // models without defined overrides
+ bool mHasConflicts;
+};
+typedef std::map<std::string, LLJointOverrideData> joint_override_data_map_t;
class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
@@ -80,6 +70,7 @@ public:
virtual ~LLFloaterModelPreview();
virtual BOOL postBuild();
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void initModelPreview();
@@ -93,6 +84,11 @@ public:
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
+ static void addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod = -1);
+ static void addStringToLog(const std::string& str, bool flash);
+ static void addStringToLog(const std::ostringstream& strm, bool flash);
+ void clearAvatarTab(); // clears table
+ void updateAvatarTab(bool highlight_overrides); // populates table and data as nessesary
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
void setPreviewLOD(S32 lod);
@@ -107,13 +103,17 @@ public:
void loadModel(S32 lod);
void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
+
+ void loadHighLodModel();
void onViewOptionChecked(LLUICtrl* ctrl);
+ void onUploadOptionChecked(LLUICtrl* ctrl);
bool isViewOptionChecked(const LLSD& userdata);
bool isViewOptionEnabled(const LLSD& userdata);
void setViewOptionEnabled(const std::string& option, bool enabled);
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
+ void onShowSkinWeightChecked(LLUICtrl* ctrl);
bool isModelLoading();
@@ -125,7 +125,7 @@ public:
/*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
void handleModelPhysicsFeeReceived();
- /*virtual*/ void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason);
+ /*virtual*/ void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason, const LLSD& result);
/*virtual*/ void onModelUploadSuccess();
@@ -142,8 +142,6 @@ protected:
static void onImportScaleCommit(LLUICtrl*, void*);
static void onPelvisOffsetCommit(LLUICtrl*, void*);
- static void onUploadJointsCommit(LLUICtrl*,void*);
- static void onUploadSkinCommit(LLUICtrl*,void*);
static void onPreviewLODCommit(LLUICtrl*,void*);
@@ -154,6 +152,7 @@ protected:
static void onAutoFillCommit(LLUICtrl*,void*);
void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+ void draw3dPreview();
static void onExplodeCommit(LLUICtrl*, void*);
@@ -175,11 +174,15 @@ protected:
// FIXME - this function and mStatusMessage have no visible effect, and the
// actual status messages are managed by directly manipulation of
// the UI element.
- void setStatusMessage(const std::string& msg);
+ void setStatusMessage(const std::string& msg);
+ void addStringToLogTab(const std::string& str, bool flash);
+
+ void setCtrlLoadFromFile(S32 lod);
LLModelPreview* mModelPreview;
LLPhysicsDecomp::decomp_params mDecompParams;
+ LLPhysicsDecomp::decomp_params mDefaultDecompParams;
S32 mLastMouseX;
S32 mLastMouseY;
@@ -203,221 +206,34 @@ protected:
LLSD mModelPhysicsFee;
private:
- void onClickCalculateBtn();
- void toggleCalculateButton();
+ void onClickCalculateBtn();
+ void onJointListSelection();
void onLoDSourceCommit(S32 lod);
+ void modelUpdated(bool calculate_visible);
+
// Toggles between "Calculate weights & fee" and "Upload" buttons.
+ void toggleCalculateButton();
void toggleCalculateButton(bool visible);
// resets display options of model preview to their defaults.
void resetDisplayOptions();
+ void resetUploadOptions();
+ void clearLogTab();
+
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
LLButton* mUploadBtn;
LLButton* mCalculateBtn;
-};
-
-class LLMeshFilePicker : public LLFilePickerThread
-{
-public:
- LLMeshFilePicker(LLModelPreview* mp, S32 lod);
- virtual void notify(const std::vector<std::string>& filenames);
-
-private:
- LLModelPreview* mMP;
- S32 mLOD;
-};
-
-
-class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
-{
- typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
- typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
- typedef boost::signals2::signal<void (bool)> model_updated_signal_t;
-
-public:
-
- typedef enum
- {
- LOD_FROM_FILE = 0,
- GENERATE,
- USE_LOD_ABOVE,
- } eLoDMode;
-
-public:
- LLModelPreview(S32 width, S32 height, LLFloater* fmp);
- virtual ~LLModelPreview();
-
- void resetPreviewTarget();
- void setPreviewTarget(F32 distance);
- void setTexture(U32 name) { mTextureName = name; }
-
- void setPhysicsFromLOD(S32 lod);
- BOOL render();
- void update();
- void genBuffers(S32 lod, bool skinned);
- void clearBuffers();
- void refresh();
- void rotate(F32 yaw_radians, F32 pitch_radians);
- void zoom(F32 zoom_amt);
- void pan(F32 right, F32 up);
- virtual BOOL needsRender() { return mNeedsUpdate; }
- void setPreviewLOD(S32 lod);
- void clearModel(S32 lod);
- void getJointAliases(JointMap& joint_map);
- void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
- void loadModelCallback(S32 lod);
- bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); }
- void queryLODs() { mGenLOD = true; };
- void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
- void generateNormals();
- void restoreNormals();
- U32 calcResourceCost();
- void rebuildUploadData();
- void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position);
- void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position);
- void clearIncompatible(S32 lod);
- void updateStatusMessages();
- void updateLodControls(S32 lod);
- void clearGLODGroup();
- void onLODParamCommit(S32 lod, bool enforce_tri_limit);
- void addEmptyFace( LLModel* pTarget );
-
- const bool getModelPivot( void ) const { return mHasPivot; }
- void setHasPivot( bool val ) { mHasPivot = val; }
- void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
-
- //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
- //Accessors for joint position upload friendly rigs
- const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
- void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
-
- //Accessors for the legacy rigs
- const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
- void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
-
- static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
- static bool lodQueryCallback();
-
- boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); }
- boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); }
- boost::signals2::connection setModelUpdatedCallback( const model_updated_signal_t::slot_type& cb ){ return mModelUpdatedSignal.connect(cb); }
-
- void setLoadState( U32 state ) { mLoadState = state; }
- U32 getLoadState() { return mLoadState; }
-
- static bool sIgnoreLoadedCallback;
- std::vector<S32> mLodsQuery;
- std::vector<S32> mLodsWithParsingError;
-
-protected:
-
- static void loadedCallback(LLModelLoader::scene& scene,LLModelLoader::model_list& model_list, S32 lod, void* opaque);
- static void stateChangedCallback(U32 state, void* opaque);
-
- static LLJoint* lookupJointByName(const std::string&, void* opaque);
- static U32 loadTextures(LLImportMaterial& material, void* opaque);
-
-private:
- //Utility function for controller vertex compare
- bool verifyCount( int expected, int result );
- //Creates the dummy avatar for the preview window
- void createPreviewAvatar( void );
- //Accessor for the dummy avatar
- LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
- // Count amount of original models, excluding sub-models
- static U32 countRootModels(LLModelLoader::model_list models);
-
- protected:
- friend class LLModelLoader;
- friend class LLFloaterModelPreview;
- friend class LLFloaterModelPreview::DecompRequest;
- friend class LLPhysicsDecomp;
-
- LLFloater* mFMP;
-
- BOOL mNeedsUpdate;
- bool mDirty;
- bool mGenLOD;
- U32 mTextureName;
- F32 mCameraDistance;
- F32 mCameraYaw;
- F32 mCameraPitch;
- F32 mCameraZoom;
- LLVector3 mCameraOffset;
- LLVector3 mPreviewTarget;
- LLVector3 mPreviewScale;
- S32 mPreviewLOD;
- S32 mPhysicsSearchLOD;
- U32 mResourceCost;
- std::string mLODFile[LLModel::NUM_LODS];
- bool mLoading;
- U32 mLoadState;
- bool mResetJoints;
- bool mModelNoErrors;
-
- std::map<std::string, bool> mViewOption;
-
- //GLOD object parameters (must rebuild object if these change)
- bool mLODFrozen;
- F32 mBuildShareTolerance;
- U32 mBuildQueueMode;
- U32 mBuildOperator;
- U32 mBuildBorderMode;
- U32 mRequestedLoDMode[LLModel::NUM_LODS];
- S32 mRequestedTriangleCount[LLModel::NUM_LODS];
- F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
- U32 mRequestedBuildOperator[LLModel::NUM_LODS];
- U32 mRequestedQueueMode[LLModel::NUM_LODS];
- U32 mRequestedBorderMode[LLModel::NUM_LODS];
- F32 mRequestedShareTolerance[LLModel::NUM_LODS];
- F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
-
- LLModelLoader* mModelLoader;
-
- LLModelLoader::scene mScene[LLModel::NUM_LODS];
- LLModelLoader::scene mBaseScene;
-
- LLModelLoader::model_list mModel[LLModel::NUM_LODS];
- LLModelLoader::model_list mBaseModel;
-
- typedef std::vector<LLVolumeFace> v_LLVolumeFace_t;
- typedef std::vector<v_LLVolumeFace_t> vv_LLVolumeFace_t;
-
- vv_LLVolumeFace_t mModelFacesCopy[LLModel::NUM_LODS];
- vv_LLVolumeFace_t mBaseModelFacesCopy;
-
- U32 mGroup;
- std::map<LLPointer<LLModel>, U32> mObject;
- U32 mMaxTriangleLimit;
-
- LLMeshUploadThread::instance_list mUploadData;
- std::set<LLViewerFetchedTexture * > mTextureSet;
-
- //map of vertex buffers to models (one vertex buffer in vector per face in model
- std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
-
- details_signal_t mDetailsSignal;
- model_loaded_signal_t mModelLoadedSignal;
- model_updated_signal_t mModelUpdatedSignal;
-
- LLVector3 mModelPivot;
- bool mHasPivot;
-
- float mPelvisZOffset;
-
- bool mRigValidJointUpload;
- bool mLegacyRigValid;
-
- bool mLastJointUpdate;
+ LLViewerTextEditor* mUploadLogText;
+ LLTabContainer* mTabContainer;
- JointNameSet mJointsFromNode;
- JointTransformMap mJointTransformMap;
+ S32 mAvatarTabIndex; // just to avoid any issues in case of xml changes
+ std::string mSelectedJointName;
- LLPointer<LLVOAvatar> mPreviewAvatar;
+ joint_override_data_map_t mJointOverrides[LLModel::NUM_LODS];
};
#endif // LL_LLFLOATERMODELPREVIEW_H
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
index 0d4c834122..721fce059e 100644
--- a/indra/newview/llfloatermodeluploadbase.h
+++ b/indra/newview/llfloatermodeluploadbase.h
@@ -45,7 +45,7 @@ public:
virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
- virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason) = 0;
+ virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason, const LLSD& result) = 0;
virtual void onModelUploadSuccess() {};
diff --git a/indra/newview/llfloatermyenvironment.cpp b/indra/newview/llfloatermyenvironment.cpp
new file mode 100644
index 0000000000..21d106c8b1
--- /dev/null
+++ b/indra/newview/llfloatermyenvironment.cpp
@@ -0,0 +1,459 @@
+/**
+ * @file llfloatergesture.cpp
+ * @brief LLFloaterMyEnvironment class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermyenvironment.h"
+
+#include "llinventory.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+
+#include "llagent.h"
+#include "llclipboard.h"
+#include "llcheckboxctrl.h"
+#include "llviewerinventory.h"
+#include "llenvironment.h"
+#include "llparcel.h"
+#include "llviewerparcelmgr.h"
+
+//=========================================================================
+namespace
+{
+ const std::string CHECK_DAYS("chk_days");
+ const std::string CHECK_SKIES("chk_skies");
+ const std::string CHECK_WATER("chk_water");
+ const std::string FLT_SEARCH("flt_search");
+ const std::string PANEL_SETTINGS("pnl_settings");
+ const std::string CHECK_SHOWFOLDERS("chk_showfolders");
+ const std::string BUTTON_NEWSETTINGS("btn_gear");
+ const std::string BUTTON_GEAR("btn_newsettings");
+ const std::string BUTTON_DELETE("btn_del");
+
+
+ const std::string ACTION_DOCREATE("MyEnvironments.DoCreate");
+ const std::string ACTION_DOEDIT("MyEnvironments.DoEdit");
+ const std::string ACTION_DOAPPLY("MyEnvironments.DoApply");
+ const std::string ACTION_COPYPASTE("MyEnvironments.CopyPaste");
+ const std::string ENABLE_ACTION("MyEnvironments.EnableAction");
+ const std::string ENABLE_CANAPPLY("MyEnvironments.CanApply");
+ const std::string ENABLE_ENVIRONMENT("MyEnvironments.EnvironmentEnabled");
+
+ const std::string PARAMETER_REGION("region");
+ const std::string PARAMETER_PARCEL("parcel");
+ const std::string PARAMETER_LOCAL("local");
+
+ const std::string PARAMETER_EDIT("edit");
+ const std::string PARAMETER_COPY("copy");
+ const std::string PARAMETER_PASTE("paste");
+ const std::string PARAMETER_COPYUUID("copy_uuid");
+}
+
+//=========================================================================
+LLFloaterMyEnvironment::LLFloaterMyEnvironment(const LLSD& key) :
+ LLFloater(key),
+ mInventoryList(nullptr),
+ mShowFolders(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS),
+ mTypeFilter((0x01 << static_cast<U64>(LLSettingsType::ST_DAYCYCLE)) | (0x01 << static_cast<U64>(LLSettingsType::ST_SKY)) | (0x01 << static_cast<U64>(LLSettingsType::ST_WATER))),
+ mSelectedAsset()
+{
+ mCommitCallbackRegistrar.add(ACTION_DOCREATE, [this](LLUICtrl *, const LLSD &userdata) { onDoCreate(userdata); });
+ mCommitCallbackRegistrar.add(ACTION_DOEDIT, [this](LLUICtrl *, const LLSD &userdata) { mInventoryList->openSelected(); });
+ mCommitCallbackRegistrar.add(ACTION_DOAPPLY, [this](LLUICtrl *, const LLSD &userdata) { onDoApply(userdata.asString()); });
+ mCommitCallbackRegistrar.add(ACTION_COPYPASTE, [this](LLUICtrl *, const LLSD &userdata) { mInventoryList->doToSelected(userdata.asString()); });
+
+ mEnableCallbackRegistrar.add(ENABLE_ACTION, [this](LLUICtrl *, const LLSD &userdata) { return canAction(userdata.asString()); });
+ mEnableCallbackRegistrar.add(ENABLE_CANAPPLY, [this](LLUICtrl *, const LLSD &userdata) { return canApply(userdata.asString()); });
+ mEnableCallbackRegistrar.add(ENABLE_ENVIRONMENT, [](LLUICtrl *, const LLSD &) { return LLEnvironment::instance().isInventoryEnabled(); });
+
+}
+
+LLFloaterMyEnvironment::~LLFloaterMyEnvironment()
+{
+}
+
+
+BOOL LLFloaterMyEnvironment::postBuild()
+{
+ mInventoryList = getChild<LLInventoryPanel>(PANEL_SETTINGS);
+
+ if (mInventoryList)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_SETTINGS;
+
+ mInventoryList->setFilterTypes(filter_types);
+
+ mInventoryList->setSelectCallback([this](const std::deque<LLFolderViewItem*>&, BOOL) { onSelectionChange(); });
+ mInventoryList->setShowFolderState(mShowFolders);
+ mInventoryList->setFilterSettingsTypes(mTypeFilter);
+ }
+
+ childSetCommitCallback(CHECK_DAYS, [this](LLUICtrl*, void*) { onFilterCheckChange(); }, nullptr);
+ childSetCommitCallback(CHECK_SKIES, [this](LLUICtrl*, void*) { onFilterCheckChange(); }, nullptr);
+ childSetCommitCallback(CHECK_WATER, [this](LLUICtrl*, void*) { onFilterCheckChange(); }, nullptr);
+ childSetCommitCallback(CHECK_SHOWFOLDERS, [this](LLUICtrl*, void*) { onShowFoldersChange(); }, nullptr);
+
+ mFilterEdit = getChild<LLFilterEditor>(FLT_SEARCH);
+ mFilterEdit->setCommitCallback([this](LLUICtrl*, const LLSD& param){ onFilterEdit(param.asString()); });
+
+ childSetCommitCallback(BUTTON_DELETE, [this](LLUICtrl *, void*) { onDeleteSelected(); }, nullptr);
+ mSavedFolderState.setApply(FALSE);
+ return TRUE;
+}
+
+void LLFloaterMyEnvironment::refresh()
+{
+ getChild<LLCheckBoxCtrl>(CHECK_SHOWFOLDERS)->setValue(LLSD::Boolean(mShowFolders == LLInventoryFilter::SHOW_ALL_FOLDERS));
+
+ getChild<LLCheckBoxCtrl>(CHECK_DAYS)->setValue(LLSD::Boolean(mTypeFilter & (0x01 << static_cast<U64>(LLSettingsType::ST_DAYCYCLE))));
+ getChild<LLCheckBoxCtrl>(CHECK_SKIES)->setValue(LLSD::Boolean(mTypeFilter & (0x01 << static_cast<U64>(LLSettingsType::ST_SKY))));
+ getChild<LLCheckBoxCtrl>(CHECK_WATER)->setValue(LLSD::Boolean(mTypeFilter & (0x01 << static_cast<U64>(LLSettingsType::ST_WATER))));
+
+ refreshButtonStates();
+
+}
+
+void LLFloaterMyEnvironment::onOpen(const LLSD& key)
+{
+ LLFloater::onOpen(key);
+
+ if (key.has("asset_id") && mInventoryList)
+ {
+ mSelectedAsset = key["asset_id"].asUUID();
+
+ if (!mSelectedAsset.isNull())
+ {
+ LLUUID obj_id = findItemByAssetId(mSelectedAsset, false, false);
+ if (!obj_id.isNull())
+ mInventoryList->setSelection(obj_id, false);
+ }
+ }
+ else
+ {
+ mSelectedAsset.setNull();
+ }
+
+ refresh();
+}
+
+//-------------------------------------------------------------------------
+void LLFloaterMyEnvironment::onShowFoldersChange()
+{
+ bool show_check(getChild<LLCheckBoxCtrl>(CHECK_SHOWFOLDERS)->getValue().asBoolean());
+
+ mShowFolders = (show_check) ? LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS;
+
+ if (mInventoryList)
+ mInventoryList->setShowFolderState(mShowFolders);
+}
+
+void LLFloaterMyEnvironment::onFilterCheckChange()
+{
+ mTypeFilter = 0x0;
+
+ if (getChild<LLCheckBoxCtrl>(CHECK_DAYS)->getValue().asBoolean())
+ mTypeFilter |= 0x01 << static_cast<U64>(LLSettingsType::ST_DAYCYCLE);
+ if (getChild<LLCheckBoxCtrl>(CHECK_SKIES)->getValue().asBoolean())
+ mTypeFilter |= 0x01 << static_cast<U64>(LLSettingsType::ST_SKY);
+ if (getChild<LLCheckBoxCtrl>(CHECK_WATER)->getValue().asBoolean())
+ mTypeFilter |= 0x01 << static_cast<U64>(LLSettingsType::ST_WATER);
+
+ if (mInventoryList)
+ mInventoryList->setFilterSettingsTypes(mTypeFilter);
+}
+
+void LLFloaterMyEnvironment::onSelectionChange()
+{
+ refreshButtonStates();
+}
+
+void LLFloaterMyEnvironment::onFilterEdit(const std::string& search_string)
+{
+ std::string upper_case_search_string = search_string;
+ LLStringUtil::toUpper(upper_case_search_string);
+
+ if (upper_case_search_string.empty())
+ {
+ if (mInventoryList->getFilterSubString().empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ mSavedFolderState.setApply(TRUE);
+ mInventoryList->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ // add folder with current item to list of previously opened folders
+ LLOpenFoldersWithSelection opener;
+ mInventoryList->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryList->getRootFolder()->scrollToShowSelection();
+
+ }
+ else if (mInventoryList->getFilterSubString().empty())
+ {
+ // first letter in search term, save existing folder open state
+ mSavedFolderState.setApply(FALSE);
+ mInventoryList->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ }
+
+ mInventoryList->setFilterSubString(search_string);
+}
+
+void LLFloaterMyEnvironment::onDeleteSelected()
+{
+ uuid_vec_t selected;
+
+ getSelectedIds(selected);
+ if (selected.empty())
+ return;
+
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ for (const LLUUID& itemid: selected)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(itemid);
+
+ if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_SETTINGS)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
+ new_item->setParent(trash_id);
+ new_item->updateParentOnServer(FALSE);
+ gInventory.updateItem(new_item);
+ }
+ }
+ gInventory.notifyObservers();
+}
+
+
+void LLFloaterMyEnvironment::onDoCreate(const LLSD &data)
+{
+ menu_create_inventory_item(mInventoryList, NULL, data);
+}
+
+void LLFloaterMyEnvironment::onDoApply(const std::string &context)
+{
+ uuid_vec_t selected;
+ getSelectedIds(selected);
+
+ if (selected.size() != 1) // Exactly one item selected.
+ return;
+
+ LLUUID item_id(selected.front());
+
+ LLInventoryItem* itemp = gInventory.getItem(item_id);
+
+ if (itemp && itemp->getInventoryType() == LLInventoryType::IT_SETTINGS)
+ {
+ LLUUID asset_id = itemp->getAssetUUID();
+ std::string name = itemp->getName();
+
+ U32 flags(0);
+
+ if (!itemp->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOMOD;
+ if (!itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOTRANS;
+
+ if (context == PARAMETER_REGION)
+ {
+ LLEnvironment::instance().updateRegion(asset_id, name, LLEnvironment::NO_TRACK, -1, -1, flags);
+ LLEnvironment::instance().setSharedEnvironment();
+ }
+ else if (context == PARAMETER_PARCEL)
+ {
+ LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+ if (!parcel)
+ {
+ LL_WARNS("ENVIRONMENT") << "Unable to determine parcel." << LL_ENDL;
+ return;
+ }
+ LLEnvironment::instance().updateParcel(parcel->getLocalID(), asset_id, name, LLEnvironment::NO_TRACK, -1, -1, flags);
+ LLEnvironment::instance().setSharedEnvironment();
+ }
+ else if (context == PARAMETER_LOCAL)
+ {
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ }
+ }
+}
+
+bool LLFloaterMyEnvironment::canAction(const std::string &context)
+{
+ uuid_vec_t selected;
+ getSelectedIds(selected);
+
+ if (selected.empty())
+ return false;
+
+ if (context == PARAMETER_EDIT)
+ {
+ return (selected.size() == 1) && isSettingSelected(selected.front());
+ }
+ else if (context == PARAMETER_COPY)
+ {
+ for (std::vector<LLUUID>::iterator it = selected.begin(); it != selected.end(); it++)
+ {
+ if(!isSettingSelected(*it))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else if (context == PARAMETER_PASTE)
+ {
+ if (!LLClipboard::instance().hasContents())
+ return false;
+
+ std::vector<LLUUID> ids;
+ LLClipboard::instance().pasteFromClipboard(ids);
+ for (std::vector<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ if (!isSettingSelected(*it))
+ {
+ return false;
+ }
+ }
+ return (selected.size() == 1);
+ }
+ else if (context == PARAMETER_COPYUUID)
+ {
+ return (selected.size() == 1) && isSettingSelected(selected.front());
+ }
+
+ return false;
+}
+
+bool LLFloaterMyEnvironment::canApply(const std::string &context)
+{
+ uuid_vec_t selected;
+ getSelectedIds(selected);
+
+ if (selected.size() != 1) // Exactly one item selected.
+ return false;
+
+ if (context == PARAMETER_REGION)
+ {
+ return LLEnvironment::instance().canAgentUpdateRegionEnvironment();
+ }
+ else if (context == PARAMETER_PARCEL)
+ {
+ return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+ }
+ else
+ {
+ return (context == PARAMETER_LOCAL);
+ }
+}
+
+//-------------------------------------------------------------------------
+void LLFloaterMyEnvironment::refreshButtonStates()
+{
+ bool settings_ok = LLEnvironment::instance().isInventoryEnabled();
+
+ uuid_vec_t selected;
+ getSelectedIds(selected);
+
+ getChild<LLUICtrl>(BUTTON_GEAR)->setEnabled(settings_ok);
+ getChild<LLUICtrl>(BUTTON_NEWSETTINGS)->setEnabled(true);
+ getChild<LLUICtrl>(BUTTON_DELETE)->setEnabled(settings_ok && !selected.empty());
+}
+
+//-------------------------------------------------------------------------
+LLUUID LLFloaterMyEnvironment::findItemByAssetId(LLUUID asset_id, bool copyable_only, bool ignore_library)
+{
+ /*TODO: Rider: Move this to gInventory? */
+
+ 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);
+
+ if (!items.empty())
+ {
+ // search for copyable version first
+ for (auto & item : items)
+ {
+ const LLPermissions& item_permissions = item->getPermissions();
+ if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(item->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return item->getUUID();
+ }
+ }
+ }
+ // otherwise just return first instance, unless copyable requested
+ if (copyable_only)
+ {
+ return LLUUID::null;
+ }
+ else
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return items[0]->getUUID();
+ }
+ }
+ }
+
+ return LLUUID::null;
+}
+
+bool LLFloaterMyEnvironment::isSettingSelected(LLUUID item_id)
+{
+ LLInventoryItem* itemp = gInventory.getItem(item_id);
+
+ if (itemp && itemp->getInventoryType() == LLInventoryType::IT_SETTINGS)
+ {
+ return true;
+ }
+ return false;
+}
+
+void LLFloaterMyEnvironment::getSelectedIds(uuid_vec_t& ids) const
+{
+ LLInventoryPanel::selected_items_t items = mInventoryList->getSelectedItems();
+
+ for (auto itemview : items)
+ {
+ LLFolderViewModelItemInventory* itemp = static_cast<LLFolderViewModelItemInventory*>(itemview->getViewModelItem());
+ ids.push_back(itemp->getUUID());
+ }
+}
diff --git a/indra/newview/llfloatermyenvironment.h b/indra/newview/llfloatermyenvironment.h
new file mode 100644
index 0000000000..fea0981590
--- /dev/null
+++ b/indra/newview/llfloatermyenvironment.h
@@ -0,0 +1,78 @@
+/**
+ * @file llfloatermyenvironment.h
+ * @brief LLFloaterMyEnvironment class header file
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#ifndef LL_LLFLOATERMYENVIRONMENT_H
+#define LL_LLFLOATERMYENVIRONMENT_H
+#include <vector>
+
+#include "llfloater.h"
+#include "llinventoryobserver.h"
+#include "llinventoryfilter.h"
+#include "llfiltereditor.h"
+
+class LLInventoryPanel;
+
+class LLFloaterMyEnvironment
+: public LLFloater, LLInventoryFetchDescendentsObserver
+{
+ LOG_CLASS(LLFloaterMyEnvironment);
+public:
+ LLFloaterMyEnvironment(const LLSD& key);
+ virtual ~LLFloaterMyEnvironment();
+
+ virtual BOOL postBuild() override;
+ virtual void refresh() override;
+
+ virtual void onOpen(const LLSD& key) override;
+
+private:
+ LLInventoryPanel * mInventoryList;
+ LLFilterEditor * mFilterEdit;
+ U64 mTypeFilter;
+ LLInventoryFilter::EFolderShow mShowFolders;
+ LLUUID mSelectedAsset;
+ LLSaveFolderState mSavedFolderState;
+
+ void onShowFoldersChange();
+ void onFilterCheckChange();
+ void onFilterEdit(const std::string& search_string);
+ void onSelectionChange();
+ void onDeleteSelected();
+ void onDoCreate(const LLSD &data);
+ void onDoApply(const std::string &context);
+ bool canAction(const std::string &context);
+ bool canApply(const std::string &context);
+
+ void getSelectedIds(uuid_vec_t& ids) const;
+ void refreshButtonStates();
+
+ bool isSettingSelected(LLUUID item_id);
+
+ static LLUUID findItemByAssetId(LLUUID asset_id, bool copyable_only, bool ignore_library);
+};
+
+
+#endif
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index c9a689281e..1e9549a04e 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -46,12 +46,13 @@
#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
#include "llstring.h"
-#include "lleconomy.h"
#include "llpermissions.h"
+#include "lltrans.h"
// linden includes
#include "llassetstorage.h"
#include "llinventorytype.h"
+#include "llagentbenefits.h"
const S32 PREVIEW_LINE_HEIGHT = 19;
const S32 PREVIEW_BORDER_WIDTH = 2;
@@ -123,13 +124,39 @@ BOOL LLFloaterNameDesc::postBuild()
// Cancel button
getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this));
- getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload() ));
+ S32 expected_upload_cost = getExpectedUploadCost();
+ getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", expected_upload_cost));
+
+ LLTextBox* info_text = getChild<LLTextBox>("info_text");
+ if (info_text)
+ {
+ info_text->setValue(LLTrans::getString("UploadFeeInfo"));
+ }
setDefaultBtn("ok_btn");
return TRUE;
}
+S32 LLFloaterNameDesc::getExpectedUploadCost() const
+{
+ std::string exten = gDirUtilp->getExtension(mFilename);
+ LLAssetType::EType asset_type;
+ S32 upload_cost = -1;
+ if (LLResourceUploadInfo::findAssetTypeOfExtension(exten, asset_type))
+ {
+ if (!LLAgentBenefitsMgr::current().findUploadCost(asset_type, upload_cost))
+ {
+ LL_WARNS() << "Unable to find upload cost for asset type " << asset_type << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Unable to find upload cost for " << mFilename << LL_ENDL;
+ }
+ return upload_cost;
+}
+
//-----------------------------------------------------------------------------
// LLFloaterNameDesc()
//-----------------------------------------------------------------------------
@@ -161,15 +188,14 @@ void LLFloaterNameDesc::onBtnOK( )
{
getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
-
+ LLAssetStorage::LLStoreAssetCallback callback;
+ S32 expected_upload_cost = getExpectedUploadCost();
if (can_afford_transaction(expected_upload_cost))
{
void *nruserdata = NULL;
std::string display_name = LLStringUtil::null;
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewFileResourceUploadInfo>(
mFilenameAndPath,
getChild<LLUICtrl>("name_form")->getValue().asString(),
getChild<LLUICtrl>("description_form")->getValue().asString(), 0,
@@ -185,7 +211,7 @@ void LLFloaterNameDesc::onBtnOK( )
{
LLSD args;
args["COST"] = llformat("%d", expected_upload_cost);
- LLNotificationsUtil::add("ErrorTextureCannotAfford", args);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
}
closeFloater(false);
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 41643681ac..589f470e82 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -30,6 +30,7 @@
#include "llfloater.h"
#include "llresizehandle.h"
#include "llstring.h"
+#include "llassettype.h"
class LLLineEditor;
class LLButton;
@@ -45,6 +46,8 @@ public:
void onBtnOK();
void onBtnCancel();
void doCommit();
+
+ S32 getExpectedUploadCost() const;
protected:
virtual void onCommit();
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 2281ea1496..649a107d74 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -121,7 +121,8 @@ const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
"Scripts",
"Notecards",
"Gestures",
- "Wearables"
+ "Wearables",
+ "Settings"
};
BOOL LLFloaterPermsDefault::postBuild()
@@ -177,7 +178,6 @@ void LLFloaterPermsDefault::sendInitialPerms()
if(!mCapSent)
{
updateCap();
- setCapSent(true);
}
}
@@ -239,7 +239,7 @@ void LLFloaterPermsDefault::updateCapCoro(std::string url)
{
const std::string& reason = status.toString();
// Do not display the same error more than once in a row
- if (reason != previousReason)
+ if ((reason != previousReason) && mCapSent)
{
previousReason = reason;
LLSD args;
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index e866b6de7d..02359a256e 100644
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -74,6 +74,7 @@ enum Categories
CAT_NOTECARDS,
CAT_GESTURES,
CAT_WEARABLES,
+ CAT_SETTINGS,
CAT_LAST
};
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index e0a3585c93..6bf2136f60 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -71,8 +71,9 @@
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewercamera.h"
-#include "llviewerwindow.h"
+#include "llviewereventrecorder.h"
#include "llviewermessage.h"
+#include "llviewerwindow.h"
#include "llviewershadermgr.h"
#include "llviewerthrottle.h"
#include "llvoavatarself.h"
@@ -159,87 +160,6 @@ struct LabelTable : public LLInitParam::Block<LabelTable>
{}
};
-class LLVoiceSetKeyDialog : public LLModalDialog
-{
-public:
- LLVoiceSetKeyDialog(const LLSD& key);
- ~LLVoiceSetKeyDialog();
-
- /*virtual*/ BOOL postBuild();
-
- void setParent(LLFloaterPreference* parent) { mParent = parent; }
-
- BOOL handleKeyHere(KEY key, MASK mask);
- BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
- static void onCancel(void* user_data);
-
-private:
- LLFloaterPreference* mParent;
-};
-
-LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key)
- : LLModalDialog(key),
- mParent(NULL)
-{
-}
-
-//virtual
-BOOL LLVoiceSetKeyDialog::postBuild()
-{
- childSetAction("Cancel", onCancel, this);
- getChild<LLUICtrl>("Cancel")->setFocus(TRUE);
-
- gFocusMgr.setKeystrokesOnly(TRUE);
-
- return TRUE;
-}
-
-LLVoiceSetKeyDialog::~LLVoiceSetKeyDialog()
-{
-}
-
-BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
-{
- BOOL result = TRUE;
-
- if (key == 'Q' && mask == MASK_CONTROL)
- {
- result = FALSE;
- }
- else if (mParent)
- {
- mParent->setKey(key);
- }
- closeFloater();
- return result;
-}
-
-BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
-{
- BOOL result = FALSE;
- if (down
- && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5)
- && mask == 0)
- {
- mParent->setMouse(clicktype);
- result = TRUE;
- closeFloater();
- }
- else
- {
- result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
- }
-
- return result;
-}
-
-//static
-void LLVoiceSetKeyDialog::onCancel(void* user_data)
-{
- LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data;
- self->closeFloater();
-}
-
// global functions
@@ -319,37 +239,6 @@ void handleAppearanceCameraMovementChanged(const LLSD& newvalue)
}
}
-/*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (0 == option && floater )
- {
- if ( floater )
- {
- floater->setAllIgnored();
- // LLFirstUse::disableFirstUse();
- floater->buildPopupLists();
- }
- }
- return false;
-}
-
-bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if ( 0 == option && floater )
- {
- if ( floater )
- {
- floater->resetAllIgnored();
- //LLFirstUse::resetFirstUse();
- floater->buildPopupLists();
- }
- }
- return false;
-}
-*/
-
void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
{
numerator = 0;
@@ -374,8 +263,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mGotPersonalInfo(false),
mOriginalIMViaEmail(false),
mLanguageChanged(false),
- mAvatarDataInitialized(false),
- mClickActionDirty(false)
+ mAvatarDataInitialized(false)
{
LLConversationLog::instance().addObserver(this);
@@ -384,7 +272,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
static bool registered_dialog = false;
if (!registered_dialog)
{
- LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
+ LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSetKeyBindDialog>);
registered_dialog = true;
}
@@ -397,8 +285,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.ResetCache", boost::bind(&LLFloaterPreference::onClickResetCache, this));
mCommitCallbackRegistrar.add("Pref.ClickSkin", boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
mCommitCallbackRegistrar.add("Pref.SelectSkin", boost::bind(&LLFloaterPreference::onSelectSkin, this));
- mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this));
- mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this));
mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
@@ -407,7 +293,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
- mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
+ mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this));
mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
@@ -419,6 +305,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
+ mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
@@ -692,12 +579,6 @@ void LLFloaterPreference::apply()
}
saveAvatarProperties();
-
- if (mClickActionDirty)
- {
- updateClickActionSettings();
- mClickActionDirty = false;
- }
}
void LLFloaterPreference::cancel()
@@ -724,17 +605,13 @@ void LLFloaterPreference::cancel()
// hide spellchecker settings folder
LLFloaterReg::hideInstance("prefs_spellchecker");
- // hide advancede floater
+ // hide advanced graphics floater
LLFloaterReg::hideInstance("prefs_graphics_advanced");
// reverts any changes to current skin
gSavedSettings.setString("SkinCurrent", sSkin);
- if (mClickActionDirty)
- {
- updateClickActionControls();
- mClickActionDirty = false;
- }
+ updateClickActionViews();
LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
if (advanced_proxy_settings)
@@ -819,7 +696,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
onChangeAnimationFolder();
// Load (double-)click to walk/teleport settings.
- updateClickActionControls();
+ updateClickActionViews();
// Enabled/disabled popups, might have been changed by user actions
// while preferences floater was closed.
@@ -843,7 +720,8 @@ void LLFloaterPreference::onOpen(const LLSD& key)
saveSettings();
// Make sure there is a default preference file
- LLPresetsManager::getInstance()->createMissingDefault();
+ LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
+ LLPresetsManager::getInstance()->createMissingDefault(PRESETS_GRAPHIC);
bool started = (LLStartUp::getStartupState() == STATE_STARTED);
@@ -852,12 +730,15 @@ void LLFloaterPreference::onOpen(const LLSD& key)
LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
- load_btn->setEnabled(started);
- save_btn->setEnabled(started);
- delete_btn->setEnabled(started);
- exceptions_btn->setEnabled(started);
+ if (load_btn && save_btn && delete_btn && exceptions_btn)
+ {
+ load_btn->setEnabled(started);
+ save_btn->setEnabled(started);
+ delete_btn->setEnabled(started);
+ exceptions_btn->setEnabled(started);
+ }
- collectSearchableItems();
+ collectSearchableItems();
if (!mFilterEdit->getText().empty())
{
mFilterEdit->setText(LLStringExplicit(""));
@@ -865,12 +746,23 @@ void LLFloaterPreference::onOpen(const LLSD& key)
}
}
-void LLFloaterPreference::onVertexShaderEnable()
+void LLFloaterPreference::onRenderOptionEnable()
{
refreshEnabledGraphics();
}
-void LLFloaterPreferenceGraphicsAdvanced::onVertexShaderEnable()
+void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable()
+{
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->refresh();
+ }
+
+ refreshEnabledGraphics();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
{
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
if (instance)
@@ -1078,6 +970,7 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata)
if (userdata.asString() == "closeadvanced")
{
LLFloaterReg::hideInstance("prefs_graphics_advanced");
+ updateMaxComplexity();
}
else
{
@@ -1241,7 +1134,7 @@ void LLFloaterPreference::buildPopupLists()
LLNotificationFormPtr formp = templatep->mForm;
LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
- if (ignore == LLNotificationForm::IGNORE_NO)
+ if (ignore <= LLNotificationForm::IGNORE_NO)
continue;
LLSD row;
@@ -1266,12 +1159,12 @@ void LLFloaterPreference::buildPopupLists()
if (it->second.asBoolean())
{
row["columns"][1]["value"] = formp->getElement(it->first)["ignore"].asString();
+ row["columns"][1]["font"] = "SANSSERIF_SMALL";
+ row["columns"][1]["width"] = 360;
break;
}
}
}
- row["columns"][1]["font"] = "SANSSERIF_SMALL";
- row["columns"][1]["width"] = 360;
}
item = disabled_popups.addElement(row);
}
@@ -1293,22 +1186,23 @@ void LLFloaterPreference::refreshEnabledState()
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
// if vertex shaders off, disable all shader related products
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") ||
- !LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
ctrl_wind_light->setEnabled(FALSE);
ctrl_wind_light->setValue(FALSE);
}
else
{
- ctrl_wind_light->setEnabled(gSavedSettings.getBOOL("VertexShaderEnable"));
+ 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") && gSavedSettings.getBOOL("VertexShaderEnable");
+ BOOL transparent_water = LLFeatureManager::getInstance()->isFeatureAvailable("RenderTransparentWater") && gSavedSettings.getBOOL("RenderTransparentWater");
+ BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
+ transparent_water &&
shaders &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -1328,12 +1222,13 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
// Reflections
- BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable")
- && gGLManager.mHasCubeMap
- && LLCubeMap::sUseCubeMaps;
+ BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
ctrl_reflections->setEnabled(reflections);
reflections_text->setEnabled(reflections);
-
+
+ // Transparent Water
+ LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
+
// Bump & Shiny
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@@ -1354,59 +1249,42 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
- if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE ||
- gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
- {
- ctrl_avatar_cloth->setEnabled(FALSE);
- }
- else
- {
- ctrl_avatar_cloth->setEnabled(TRUE);
- }
-
- // Vertex Shaders
- // Global Shader Enable
- LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
- LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail"); // can be linked with control var
- LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
+ if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
+ {
+ ctrl_avatar_cloth->setEnabled(FALSE);
+ }
+ else
+ {
+ ctrl_avatar_cloth->setEnabled(TRUE);
+ }
- ctrl_shader_enable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
-
- BOOL shaders = ctrl_shader_enable->get();
- if (shaders)
- {
- terrain_detail->setEnabled(FALSE);
- terrain_text->setEnabled(FALSE);
- }
- else
- {
- terrain_detail->setEnabled(TRUE);
- terrain_text->setEnabled(TRUE);
- }
-
- // WindLight
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
- LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
+ // 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");
- // *HACK just checks to see if we can use shaders...
- // maybe some cards that use shaders, but don't support windlight
- ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders);
+ terrain_detail->setEnabled(FALSE);
+ terrain_text->setEnabled(FALSE);
- sky->setEnabled(ctrl_wind_light->get() && shaders);
- sky_text->setEnabled(ctrl_wind_light->get() && shaders);
+ // 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) &&
- shaders &&
- gGLManager.mHasFramebufferObject &&
- gSavedSettings.getBOOL("RenderAvatarVP") &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
+ //Deferred/SSAO/Shadows
+ LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+
+ BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
+ ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
+ gGLManager.mHasFramebufferObject &&
+ gSavedSettings.getBOOL("RenderAvatarVP") &&
+ (ctrl_wind_light->get()) ? TRUE : FALSE;
- ctrl_deferred->setEnabled(enabled);
+ ctrl_deferred->setEnabled(enabled);
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
@@ -1477,7 +1355,7 @@ void LLAvatarComplexityControls::setIndirectMaxNonImpostors()
{
U32 max_non_impostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
// for this one, we just need to make zero, which means off, the max value of the slider
- U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::IMPOSTORS_OFF : max_non_impostors;
+ U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER : max_non_impostors;
gSavedSettings.setU32("IndirectMaxNonImpostors", indirect_max_non_impostors);
}
@@ -1504,7 +1382,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
- LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
@@ -1514,42 +1391,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
- // if vertex shaders off, disable all shader related products
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
- {
- ctrl_shader_enable->setEnabled(FALSE);
- ctrl_shader_enable->setValue(FALSE);
-
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
-
- sky->setEnabled(FALSE);
- sky_text->setEnabled(FALSE);
-
- ctrl_reflections->setEnabled(FALSE);
- ctrl_reflections->setValue(0);
- reflections_text->setEnabled(FALSE);
-
- ctrl_avatar_vp->setEnabled(FALSE);
- ctrl_avatar_vp->setValue(FALSE);
-
- ctrl_avatar_cloth->setEnabled(FALSE);
- ctrl_avatar_cloth->setValue(FALSE);
-
- ctrl_shadows->setEnabled(FALSE);
- ctrl_shadows->setValue(0);
- shadows_text->setEnabled(FALSE);
-
- ctrl_ssao->setEnabled(FALSE);
- ctrl_ssao->setValue(FALSE);
-
- ctrl_dof->setEnabled(FALSE);
- ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
- }
-
// disabled windlight
if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
@@ -1659,6 +1500,7 @@ void LLFloaterPreference::refresh()
{
advanced->refresh();
}
+ updateClickActionViews();
}
void LLFloaterPreferenceGraphicsAdvanced::refresh()
@@ -1700,72 +1542,6 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)
refresh();
}
-void LLFloaterPreference::onClickSetKey()
-{
- LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE);
- if (dialog)
- {
- dialog->setParent(this);
- }
-}
-
-void LLFloaterPreference::setKey(KEY key)
-{
- getChild<LLUICtrl>("modifier_combo")->setValue(LLKeyboard::stringFromKey(key));
- // update the control right away since we no longer wait for apply
- getChild<LLUICtrl>("modifier_combo")->onCommit();
-}
-
-void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click)
-{
- std::string bt_name;
- std::string ctrl_value;
- switch (click)
- {
- case LLMouseHandler::CLICK_MIDDLE:
- bt_name = "middle_mouse";
- ctrl_value = MIDDLE_MOUSE_CV;
- break;
- case LLMouseHandler::CLICK_BUTTON4:
- bt_name = "button4_mouse";
- ctrl_value = MOUSE_BUTTON_4_CV;
- break;
- case LLMouseHandler::CLICK_BUTTON5:
- bt_name = "button5_mouse";
- ctrl_value = MOUSE_BUTTON_5_CV;
- break;
- default:
- break;
- }
-
- if (!ctrl_value.empty())
- {
- LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
- // We are using text control names for readability and compatibility with voice
- p2t_line_editor->setControlValue(ctrl_value);
- LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
- if (advanced_preferences)
- {
- p2t_line_editor->setValue(advanced_preferences->getString(bt_name));
- }
- }
-}
-
-void LLFloaterPreference::onClickSetMiddleMouse()
-{
- LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
-
- // update the control right away since we no longer wait for apply
- p2t_line_editor->setControlValue(MIDDLE_MOUSE_CV);
-
- //push2talk button "middle mouse" control value is in English, need to localize it for presentation
- LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
- if (advanced_preferences)
- {
- p2t_line_editor->setValue(advanced_preferences->getString("middle_mouse"));
- }
-}
-
void LLFloaterPreference::onClickSetSounds()
{
// Disable Enable gesture sounds checkbox if the master sound is disabled
@@ -1773,18 +1549,6 @@ void LLFloaterPreference::onClickSetSounds()
getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
}
-/*
-void LLFloaterPreference::onClickSkipDialogs()
-{
- LLNotificationsUtil::add("SkipShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_skip_dialogs, _1, _2, this));
-}
-
-void LLFloaterPreference::onClickResetDialogs()
-{
- LLNotificationsUtil::add("ResetShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_reset_dialogs, _1, _2, this));
-}
- */
-
void LLFloaterPreference::onClickEnablePopup()
{
LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
@@ -1823,7 +1587,7 @@ void LLFloaterPreference::resetAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
- if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(false);
}
@@ -1836,7 +1600,7 @@ void LLFloaterPreference::setAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
- if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(true);
}
@@ -1968,6 +1732,8 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
getChildView("log_path_button")->setEnabled(TRUE);
getChildView("chat_font_size")->setEnabled(TRUE);
getChildView("conversation_log_combo")->setEnabled(TRUE);
+ getChild<LLUICtrl>("voice_call_friends_only_check")->setEnabled(TRUE);
+ getChild<LLUICtrl>("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"));
}
@@ -2012,7 +1778,7 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
U32 value = ctrl->getValue().asInteger();
- if (0 == value || LLVOAvatar::IMPOSTORS_OFF <= value)
+ if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
{
value=0;
}
@@ -2076,6 +1842,14 @@ void LLFloaterPreference::updateMaxComplexity()
LLAvatarComplexityControls::updateMax(
getChild<LLSliderCtrl>("IndirectMaxComplexity"),
getChild<LLTextBox>("IndirectMaxComplexityText"));
+
+ LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced");
+ if (floater_graphics_advanced)
+ {
+ LLAvatarComplexityControls::updateMax(
+ floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+ floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText"));
+ }
}
bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
@@ -2123,6 +1897,14 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
LLAvatarComplexityControls::updateMax(
getChild<LLSliderCtrl>("IndirectMaxComplexity"),
getChild<LLTextBox>("IndirectMaxComplexityText"));
+
+ LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (floater_preferences)
+ {
+ LLAvatarComplexityControls::updateMax(
+ floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+ floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
+ }
}
void LLFloaterPreference::onChangeMaturity()
@@ -2248,7 +2030,7 @@ void LLFloaterPreference::onClickAdvanced()
void LLFloaterPreference::onClickActionChange()
{
- mClickActionDirty = true;
+ updateClickActionControls();
}
void LLFloaterPreference::onClickPermsDefault()
@@ -2256,6 +2038,11 @@ void LLFloaterPreference::onClickPermsDefault()
LLFloaterReg::showInstance("perms_default");
}
+void LLFloaterPreference::onClickRememberedUsernames()
+{
+ LLFloaterReg::showInstance("forget_username");
+}
+
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;
@@ -2283,21 +2070,81 @@ void LLFloaterPreference::onLogChatHistorySaved()
}
}
-void LLFloaterPreference::updateClickActionSettings()
+void LLFloaterPreference::updateClickActionControls()
{
- const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
- const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
-
- gSavedSettings.setBOOL("ClickToWalk", single_clk_action == 1);
- gSavedSettings.setBOOL("DoubleClickAutoPilot", double_clk_action == 1);
- gSavedSettings.setBOOL("DoubleClickTeleport", double_clk_action == 2);
+ const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
+ const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ // Potential option: make constructor of LLKeyConflictHandler private
+ // but add a getter that will return shared pointer for specific
+ // mode, pointer should only exist so long as there are external users.
+ // In such case we won't need to do this 'dynamic_cast' nightmare.
+ // updateTable() can also be avoided
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE,
+ single_clk_action == 1);
+
+ panel->setKeyBind("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 1);
+
+ panel->setKeyBind("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE,
+ double_clk_action == 2);
+
+ panel->updateAndApply();
+ }
+ }
}
-void LLFloaterPreference::updateClickActionControls()
+void LLFloaterPreference::updateClickActionViews()
{
- const bool click_to_walk = gSavedSettings.getBOOL("ClickToWalk");
- const bool dbl_click_to_walk = gSavedSettings.getBOOL("DoubleClickAutoPilot");
- const bool dbl_click_to_teleport = gSavedSettings.getBOOL("DoubleClickTeleport");
+ bool click_to_walk = false;
+ bool dbl_click_to_walk = false;
+ bool dbl_click_to_teleport = false;
+
+ // Todo: This is a very ugly way to get access to keybindings.
+ // Reconsider possible options.
+ LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+ for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+ iter != tabcontainer->getChildList()->end(); ++iter)
+ {
+ LLView* view = *iter;
+ LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+ if (panel)
+ {
+ click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_LEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_walk = panel->canKeyBindHandle("walk_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+
+ dbl_click_to_teleport = panel->canKeyBindHandle("teleport_to",
+ EMouseClickType::CLICK_DOUBLELEFT,
+ KEY_NONE,
+ MASK_NONE);
+ }
+ }
getChild<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
@@ -2484,25 +2331,6 @@ BOOL LLPanelPreference::postBuild()
getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
}
- //////////////////////PanelAdvanced ///////////////////
- if (hasChild("modifier_combo", TRUE))
- {
- //localizing if push2talk button is set to middle mouse
- std::string modifier_value = getChild<LLUICtrl>("modifier_combo")->getValue().asString();
- if (MIDDLE_MOUSE_CV == modifier_value)
- {
- getChild<LLUICtrl>("modifier_combo")->setValue(getString("middle_mouse"));
- }
- else if (MOUSE_BUTTON_4_CV == modifier_value)
- {
- getChild<LLUICtrl>("modifier_combo")->setValue(getString("button4_mouse"));
- }
- else if (MOUSE_BUTTON_5_CV == modifier_value)
- {
- getChild<LLUICtrl>("modifier_combo")->setValue(getString("button5_mouse"));
- }
- }
-
//////////////////////PanelSetup ///////////////////
if (hasChild("max_bandwidth"), TRUE)
{
@@ -2591,9 +2419,13 @@ void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLS
void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
{
- if (checkbox && checkbox->getValue())
+ if (checkbox)
{
- LLNotificationsUtil::add("FriendsAndGroupsOnly");
+ gSavedPerAccountSettings.setBOOL("VoiceCallsFriendsOnly", checkbox->getValue().asBoolean());
+ if (checkbox->getValue())
+ {
+ LLNotificationsUtil::add("FriendsAndGroupsOnly");
+ }
}
}
@@ -2668,26 +2500,23 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
- getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
+ getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}
void LLPanelPreference::deletePreset(const LLSD& user_data)
{
- std::string subdirectory = user_data.asString();
- LLFloaterReg::showInstance("delete_pref_preset", subdirectory);
+ LLFloaterReg::showInstance("delete_pref_preset", user_data.asString());
}
void LLPanelPreference::savePreset(const LLSD& user_data)
{
- std::string subdirectory = user_data.asString();
- LLFloaterReg::showInstance("save_pref_preset", subdirectory);
+ LLFloaterReg::showInstance("save_pref_preset", user_data.asString());
}
void LLPanelPreference::loadPreset(const LLSD& user_data)
{
- std::string subdirectory = user_data.asString();
- LLFloaterReg::showInstance("load_pref_preset", subdirectory);
+ LLFloaterReg::showInstance("load_pref_preset", user_data.asString());
}
void LLPanelPreference::setHardwareDefaults()
@@ -2699,7 +2528,6 @@ class LLPanelPreferencePrivacy : public LLPanelPreference
public:
LLPanelPreferencePrivacy()
{
- mAccountIndependentSettings.push_back("VoiceCallsFriendsOnly");
mAccountIndependentSettings.push_back("AutoDisengageMic");
}
@@ -2745,7 +2573,7 @@ BOOL LLPanelPreferenceGraphics::postBuild()
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPreferenceGraphics::onPresetsListChange, this));
- presetsMgr->createMissingDefault(); // a no-op after the first time, but that's ok
+ presetsMgr->createMissingDefault(PRESETS_GRAPHIC); // a no-op after the first time, but that's ok
return LLPanelPreference::postBuild();
}
@@ -2766,11 +2594,6 @@ void LLPanelPreferenceGraphics::onPresetsListChange()
{
instance->saveSettings(); //make cancel work correctly after changing the preset
}
- else
- {
- std::string dummy;
- instance->saveGraphicsPreset(dummy);
- }
}
void LLPanelPreferenceGraphics::setPresetText()
@@ -2788,7 +2611,7 @@ void LLPanelPreferenceGraphics::setPresetText()
}
}
- if (hasDirtyChilds() && !preset_graphic_active.empty())
+ if (hasDirtyChilds() && !preset_graphic_active.empty())
{
gSavedSettings.setString("PresetGraphicActive", "");
preset_graphic_active.clear();
@@ -2908,10 +2731,589 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()
resetDirtyChilds();
}
+//------------------------LLPanelPreferenceControls--------------------------------
+static LLPanelInjector<LLPanelPreferenceControls> t_pref_contrls("panel_preference_controls");
+
+LLPanelPreferenceControls::LLPanelPreferenceControls()
+ :LLPanelPreference(),
+ mEditingColumn(-1),
+ mEditingMode(0)
+{
+ // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'.
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i);
+ }
+}
+
+LLPanelPreferenceControls::~LLPanelPreferenceControls()
+{
+}
+
+BOOL LLPanelPreferenceControls::postBuild()
+{
+ // populate list of controls
+ pControlsTable = getChild<LLScrollListCtrl>("controls_list");
+ pKeyModeBox = getChild<LLComboBox>("key_mode");
+
+ pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this));
+ pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this));
+ getChild<LLButton>("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this));
+
+ return TRUE;
+}
+
+void LLPanelPreferenceControls::regenerateControls()
+{
+ mEditingMode = pKeyModeBox->getValue().asInteger();
+ mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+ populateControlTable();
+}
+
+bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filename)
+{
+ LLXMLNodePtr xmlNode;
+ LLScrollListCtrl::Contents contents;
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+ {
+ LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ return false;
+ }
+ LLXUIParser parser;
+ parser.readXUI(xmlNode, contents, filename);
+
+ if (!contents.validateBlock())
+ {
+ return false;
+ }
+
+ for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator col_it = contents.columns.begin();
+ col_it != contents.columns.end();
+ ++col_it)
+ {
+ pControlsTable->addColumn(*col_it);
+ }
+
+ return true;
+}
+
+bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
+{
+ LLXMLNodePtr xmlNode;
+ LLScrollListCtrl::Contents contents;
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+ {
+ LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ return false;
+ }
+ LLXUIParser parser;
+ parser.readXUI(xmlNode, contents, filename);
+
+ if (!contents.validateBlock())
+ {
+ return false;
+ }
+
+ LLScrollListCell::Params cell_params;
+ // init basic cell params
+ cell_params.font = LLFontGL::getFontSansSerif();
+ cell_params.font_halign = LLFontGL::LEFT;
+ cell_params.column = "";
+ cell_params.value = "";
+
+
+ for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = contents.rows.begin();
+ row_it != contents.rows.end();
+ ++row_it)
+ {
+ std::string control = row_it->value.getValue().asString();
+ if (!control.empty() && control != "menu_separator")
+ {
+ bool show = true;
+ bool enabled = mConflictHandler[mEditingMode].canAssignControl(control);
+ if (!enabled)
+ {
+ // If empty: this is a placeholder to make sure user won't assign
+ // value by accident, don't show it
+ // If not empty: predefined control combination user should see
+ // to know that combination is reserved
+ show = !mConflictHandler[mEditingMode].isControlEmpty(control);
+ // example: teleport_to and walk_to in first person view, and
+ // sitting related functions, see generatePlaceholders()
+ }
+
+ if (show)
+ {
+ // At the moment viewer is hardcoded to assume that columns are named as lst_ctrl%d
+ LLScrollListItem::Params item_params(*row_it);
+ item_params.enabled.setValue(enabled);
+
+ S32 num_columns = pControlsTable->getNumColumns();
+ for (S32 col = 1; col < num_columns; col++)
+ {
+ cell_params.column = llformat("lst_ctrl%d", col);
+ cell_params.value = mConflictHandler[mEditingMode].getControlString(control, col - 1);
+ item_params.columns.add(cell_params);
+ }
+ pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
+ }
+ }
+ else
+ {
+ // Separator example:
+ // <rows
+ // enabled = "false">
+ // <columns
+ // type = "icon"
+ // color = "0 0 0 0.7"
+ // halign = "center"
+ // value = "menu_separator"
+ // column = "lst_action" / >
+ //</rows>
+ pControlsTable->addRow(*row_it, EAddPosition::ADD_BOTTOM);
+ }
+ }
+ return true;
+}
+
+void LLPanelPreferenceControls::addControlTableSeparator()
+{
+ LLScrollListItem::Params separator_params;
+ separator_params.enabled(false);
+ LLScrollListCell::Params column_params;
+ column_params.type = "icon";
+ column_params.value = "menu_separator";
+ column_params.column = "lst_action";
+ column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
+ column_params.font_halign = LLFontGL::HCENTER;
+ separator_params.columns.add(column_params);
+ pControlsTable->addRow(separator_params, EAddPosition::ADD_BOTTOM);
+}
+
+void LLPanelPreferenceControls::populateControlTable()
+{
+ pControlsTable->clearRows();
+ pControlsTable->clearColumns();
+
+ // Add columns
+ std::string filename;
+ switch ((LLKeyConflictHandler::ESourceMode)mEditingMode)
+ {
+ case LLKeyConflictHandler::MODE_THIRD_PERSON:
+ case LLKeyConflictHandler::MODE_FIRST_PERSON:
+ case LLKeyConflictHandler::MODE_EDIT_AVATAR:
+ case LLKeyConflictHandler::MODE_SITTING:
+ filename = "control_table_contents_columns_basic.xml";
+ break;
+ default:
+ // Either unknown mode or MODE_SAVED_SETTINGS
+ // It doesn't have UI or actual settings yet
+ LL_INFOS() << "Unimplemented mode" << LL_ENDL;
+ return;
+ }
+ addControlTableColumns(filename);
+
+ // Add rows.
+ // Each file represents individual visual group (movement/camera/media...)
+ if (mEditingMode == LLKeyConflictHandler::MODE_FIRST_PERSON)
+ {
+ // Don't display whole camera and editing groups
+ addControlTableRows("control_table_contents_movement.xml");
+ addControlTableSeparator();
+ addControlTableRows("control_table_contents_media.xml");
+ }
+ // MODE_THIRD_PERSON; MODE_EDIT_AVATAR; MODE_SITTING
+ else if (mEditingMode < LLKeyConflictHandler::MODE_SAVED_SETTINGS)
+ {
+ // In case of 'sitting' mode, movements still apply due to vehicles
+ // but walk_to is not supported and will be hidden by addControlTableRows
+ addControlTableRows("control_table_contents_movement.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_camera.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_editing.xml");
+ addControlTableSeparator();
+
+ addControlTableRows("control_table_contents_media.xml");
+ }
+ else
+ {
+ LL_INFOS() << "Unimplemented mode" << LL_ENDL;
+ return;
+ }
+}
+
+void LLPanelPreferenceControls::updateTable()
+{
+ mEditingControl.clear();
+ std::vector<LLScrollListItem*> list = pControlsTable->getAllData();
+ for (S32 i = 0; i < list.size(); ++i)
+ {
+ std::string control = list[i]->getValue();
+ if (!control.empty())
+ {
+ LLScrollListCell* cell = NULL;
+
+ S32 num_columns = pControlsTable->getNumColumns();
+ for (S32 col = 1; col < num_columns; col++)
+ {
+ cell = list[i]->getColumn(col);
+ cell->setValue(mConflictHandler[mEditingMode].getControlString(control, col - 1));
+ }
+ }
+ }
+ pControlsTable->deselectAllItems();
+}
+
+void LLPanelPreferenceControls::apply()
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].saveToSettings();
+ }
+ }
+}
+
+void LLPanelPreferenceControls::cancel()
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].clear();
+ }
+ }
+ pControlsTable->clearRows();
+ pControlsTable->clearColumns();
+}
+
+void LLPanelPreferenceControls::saveSettings()
+{
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].hasUnsavedChanges())
+ {
+ mConflictHandler[i].saveToSettings();
+ mConflictHandler[i].clear();
+ }
+ }
+
+ S32 mode = pKeyModeBox->getValue().asInteger();
+ if (mConflictHandler[mode].empty() || pControlsTable->isEmpty())
+ {
+ regenerateControls();
+ }
+}
+
+void LLPanelPreferenceControls::resetDirtyChilds()
+{
+ regenerateControls();
+}
+
+void LLPanelPreferenceControls::onListCommit()
+{
+ LLScrollListItem* item = pControlsTable->getFirstSelected();
+ if (item == NULL)
+ {
+ return;
+ }
+
+ std::string control = item->getValue();
+
+ if (control.empty())
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ if (!mConflictHandler[mEditingMode].canAssignControl(control))
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ S32 cell_ind = item->getSelectedCell();
+ if (cell_ind <= 0)
+ {
+ pControlsTable->deselectAllItems();
+ return;
+ }
+
+ // List does not tell us what cell was clicked, so we have to figure it out manually, but
+ // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,
+ // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,
+ // use coordinates from hover to calculate cell
+
+ LLScrollListCell* cell = item->getColumn(cell_ind);
+ if (cell)
+ {
+ LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+ if (dialog)
+ {
+ mEditingControl = control;
+ mEditingColumn = cell_ind;
+ dialog->setParent(this, pControlsTable, DEFAULT_KEY_FILTER);
+
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ root_floater->addDependentFloater(dialog);
+ dialog->openFloater();
+ dialog->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ pControlsTable->deselectAllItems();
+ }
+}
+
+void LLPanelPreferenceControls::onModeCommit()
+{
+ mEditingMode = pKeyModeBox->getValue().asInteger();
+ if (mConflictHandler[mEditingMode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+ }
+ populateControlTable();
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsBtn()
+{
+ LLNotificationsUtil::add("PreferenceControlsDefaults", LLSD(), LLSD(), boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsResponse, this, _1, _2));
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0: // All
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ mConflictHandler[i].resetToDefaults();
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ updateTable();
+ break;
+ case 1: // Current
+ mConflictHandler[mEditingMode].resetToDefaults();
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ updateTable();
+ break;
+ case 2: // Cancel
+ default:
+ //exit;
+ break;
+ }
+}
+
+// Bypass to let Move & view read values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+bool LLPanelPreferenceControls::canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ return mConflictHandler[mode].canHandleControl(control, click, key, mask);
+}
+
+// Bypass to let Move & view modify values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+void LLPanelPreferenceControls::setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set)
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ if (mConflictHandler[mode].empty())
+ {
+ // opening for first time
+ mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+ }
+
+ if (!mConflictHandler[mode].canAssignControl(mEditingControl))
+ {
+ return;
+ }
+
+ bool already_recorded = mConflictHandler[mode].canHandleControl(control, click, key, mask);
+ if (set)
+ {
+ if (already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find free spot to add data, if no free spot, assign to first
+ S32 index = 0;
+ for (S32 i = 0; i < 3; i++)
+ {
+ if (mConflictHandler[mode].getControl(control, i).isEmpty())
+ {
+ index = i;
+ break;
+ }
+ }
+ mConflictHandler[mode].registerControl(control, index, click, key, mask, true);
+ }
+ else if (!set)
+ {
+ if (!already_recorded)
+ {
+ // nothing to do
+ return;
+ }
+
+ // find specific control and reset it
+ for (S32 i = 0; i < 3; i++)
+ {
+ LLKeyData data = mConflictHandler[mode].getControl(control, i);
+ if (data.mMouse == click && data.mKey == key && data.mMask == mask)
+ {
+ mConflictHandler[mode].clearControl(control, i);
+ }
+ }
+ }
+}
+
+void LLPanelPreferenceControls::updateAndApply()
+{
+ S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+ mConflictHandler[mode].saveToSettings(true);
+ updateTable();
+}
+
+// from LLSetKeybindDialog's interface
+bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
+{
+ if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+ {
+ return true;
+ }
+
+ if ( mEditingColumn > 0)
+ {
+ if (all_modes)
+ {
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].empty())
+ {
+ mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+ }
+ mConflictHandler[i].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+ }
+ }
+ else
+ {
+ mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+ }
+ }
+
+ updateTable();
+
+ if ((mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ && (mEditingControl == "walk_to"
+ || mEditingControl == "teleport_to"
+ || click == CLICK_LEFT
+ || click == CLICK_DOUBLELEFT))
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+
+ return true;
+}
+
+void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes)
+{
+ if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+ {
+ return;
+ }
+
+ if (mEditingColumn > 0)
+ {
+ if (all_modes)
+ {
+ for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+ {
+ if (mConflictHandler[i].empty())
+ {
+ mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+ }
+ mConflictHandler[i].resetToDefault(mEditingControl, mEditingColumn - 1);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[i].saveToSettings(true);
+ }
+ }
+ else
+ {
+ mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);
+ // Apply changes to viewer as 'temporary'
+ mConflictHandler[mEditingMode].saveToSettings(true);
+ }
+ }
+ updateTable();
+
+ if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+ {
+ // notify comboboxes in move&view about potential change
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->updateClickActionViews();
+ }
+ }
+}
+
+void LLPanelPreferenceControls::onCancelKeyBind()
+{
+ pControlsTable->deselectAllItems();
+}
+
LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
: LLFloater(key)
{
- mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onVertexShaderEnable, this));
+ mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
}
@@ -2961,6 +3363,7 @@ void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
{
instance->cancel();
}
+ updateMaxComplexity();
}
LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index d46f0deb7a..1268935712 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -37,13 +37,17 @@
#include "llavatarpropertiesprocessor.h"
#include "llconversationlog.h"
#include "llsearcheditor.h"
+#include "llsetkeybinddialog.h"
+#include "llkeyconflict.h"
class LLConversationLogObserver;
class LLPanelPreference;
class LLPanelLCD;
class LLPanelDebug;
class LLMessageSystem;
+class LLComboBox;
class LLScrollListCtrl;
+class LLScrollListCell;
class LLSliderCtrl;
class LLSD;
class LLTextBox;
@@ -102,6 +106,8 @@ public:
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
+ // updates click/double-click action controls depending on values from settings.xml
+ void updateClickActionViews();
protected:
void onBtnOK(const LLSD& userdata);
@@ -122,16 +128,14 @@ protected:
// callback for defaults
void setHardwareDefaults();
void setRecommended();
- // callback for when client turns on shaders
- void onVertexShaderEnable();
+ // callback for when client modifies a render option
+ void onRenderOptionEnable();
// callback for when client turns on impostors
void onAvatarImpostorsEnable();
// callback for commit in the "Single click on land" and "Double click on land" comboboxes.
void onClickActionChange();
- // updates click/double-click action settings depending on controls values
- void updateClickActionSettings();
- // updates click/double-click action controls depending on values from settings.xml
+ // updates click/double-click action keybindngs depending on view values
void updateClickActionControls();
public:
@@ -146,10 +150,6 @@ public:
void onClickResetCache();
void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
void onSelectSkin();
- void onClickSetKey();
- void setKey(KEY key);
- void setMouse(LLMouseHandler::EClickType click);
- void onClickSetMiddleMouse();
void onClickSetSounds();
void onClickEnablePopup();
void onClickDisablePopup();
@@ -168,7 +168,6 @@ public:
void refreshUI();
- void onCommitParcelMediaAutoPlayEnable();
void onCommitMediaEnabled();
void onCommitMusicEnabled();
void applyResolution();
@@ -181,6 +180,7 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickPermsDefault();
+ void onClickRememberedUsernames();
void onClickAutoReplace();
void onClickSpellChecker();
void onClickRenderExceptions();
@@ -191,6 +191,7 @@ public:
void buildPopupLists();
static void refreshSkin(void* data);
void selectPanel(const LLSD& name);
+ void saveCameraPreset(std::string& preset);
void saveGraphicsPreset(std::string& preset);
private:
@@ -203,7 +204,6 @@ private:
static std::string sSkin;
notifications_map mNotificationOptions;
- bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
bool mGotPersonalInfo;
bool mOriginalIMViaEmail;
bool mLanguageChanged;
@@ -214,6 +214,7 @@ private:
std::string mDirectoryVisibility;
LLAvatarData mAvatarProperties;
+ std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
@@ -288,11 +289,64 @@ protected:
bool hasDirtyChilds();
private:
-
void onPresetsListChange();
LOG_CLASS(LLPanelPreferenceGraphics);
};
+class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResponderInterface
+{
+ LOG_CLASS(LLPanelPreferenceControls);
+public:
+ LLPanelPreferenceControls();
+ virtual ~LLPanelPreferenceControls();
+
+ BOOL postBuild();
+
+ void apply();
+ void cancel();
+ void saveSettings();
+ void resetDirtyChilds();
+
+ void onListCommit();
+ void onModeCommit();
+ void onRestoreDefaultsBtn();
+ void onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response);
+
+ // Bypass to let Move & view read values without need to create own key binding handler
+ // Todo: consider a better way to share access to keybindings
+ bool canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask);
+ // Bypasses to let Move & view modify values without need to create own key binding handler
+ void setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set /*set or reset*/ );
+ void updateAndApply();
+
+ // from interface
+ /*virtual*/ bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes);
+ /*virtual*/ void onDefaultKeyBind(bool all_modes);
+ /*virtual*/ void onCancelKeyBind();
+
+private:
+ // reloads settings, discards current changes, updates table
+ void regenerateControls();
+
+ // These fuctions do not clean previous content
+ bool addControlTableColumns(const std::string &filename);
+ bool addControlTableRows(const std::string &filename);
+ void addControlTableSeparator();
+
+ // Cleans content and then adds content from xml files according to current mEditingMode
+ void populateControlTable();
+
+ // Updates keybindings from storage to table
+ void updateTable();
+
+ LLScrollListCtrl* pControlsTable;
+ LLComboBox *pKeyModeBox;
+ LLKeyConflictHandler mConflictHandler[LLKeyConflictHandler::MODE_COUNT];
+ std::string mEditingControl;
+ S32 mEditingColumn;
+ S32 mEditingMode;
+};
+
class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
{
public:
@@ -313,8 +367,9 @@ class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
static void setIndirectMaxNonImpostors();
static void setIndirectMaxArc();
void refresh();
- // callback for when client turns on shaders
- void onVertexShaderEnable();
+ // callback for when client modifies a render option
+ void onRenderOptionEnable();
+ void onAdvancedAtmosphericsEnable();
LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
};
diff --git a/indra/newview/llfloaterpreferenceviewadvanced.cpp b/indra/newview/llfloaterpreferenceviewadvanced.cpp
new file mode 100644
index 0000000000..f8db738923
--- /dev/null
+++ b/indra/newview/llfloaterpreferenceviewadvanced.cpp
@@ -0,0 +1,82 @@
+/**
+ * @file llfloaterpreferenceviewadvanced.cpp
+ * @brief floater for adjusting camera position
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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 "llagentcamera.h"
+#include "llfloaterpreferenceviewadvanced.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lluictrlfactory.h"
+#include "llspinctrl.h"
+#include "llviewercontrol.h"
+
+
+LLFloaterPreferenceViewAdvanced::LLFloaterPreferenceViewAdvanced(const LLSD& key)
+: LLFloater(key)
+{
+ mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterPreferenceViewAdvanced::onCommitSettings, this));
+}
+
+LLFloaterPreferenceViewAdvanced::~LLFloaterPreferenceViewAdvanced()
+{}
+
+void LLFloaterPreferenceViewAdvanced::updateCameraControl(const LLVector3& vector)
+{
+ getChild<LLSpinCtrl>("camera_x")->setValue(vector[VX]);
+ getChild<LLSpinCtrl>("camera_y")->setValue(vector[VY]);
+ getChild<LLSpinCtrl>("camera_z")->setValue(vector[VZ]);
+}
+
+void LLFloaterPreferenceViewAdvanced::updateFocusControl(const LLVector3d& vector3d)
+{
+ getChild<LLSpinCtrl>("focus_x")->setValue(vector3d[VX]);
+ getChild<LLSpinCtrl>("focus_y")->setValue(vector3d[VY]);
+ getChild<LLSpinCtrl>("focus_z")->setValue(vector3d[VZ]);
+}
+
+ void LLFloaterPreferenceViewAdvanced::draw()
+{
+ updateCameraControl(gAgentCamera.getCameraOffsetInitial());
+ updateFocusControl(gAgentCamera.getFocusOffsetInitial());
+
+ LLFloater::draw();
+}
+
+void LLFloaterPreferenceViewAdvanced::onCommitSettings()
+{
+ LLVector3 vector;
+ LLVector3d vector3d;
+
+ vector.mV[VX] = (F32)getChild<LLUICtrl>("camera_x")->getValue().asReal();
+ vector.mV[VY] = (F32)getChild<LLUICtrl>("camera_y")->getValue().asReal();
+ vector.mV[VZ] = (F32)getChild<LLUICtrl>("camera_z")->getValue().asReal();
+ gSavedSettings.setVector3("CameraOffsetRearView", vector);
+
+ vector3d.mdV[VX] = (F32)getChild<LLUICtrl>("focus_x")->getValue().asReal();
+ vector3d.mdV[VY] = (F32)getChild<LLUICtrl>("focus_y")->getValue().asReal();
+ vector3d.mdV[VZ] = (F32)getChild<LLUICtrl>("focus_z")->getValue().asReal();
+ gSavedSettings.setVector3d("FocusOffsetRearView", vector3d);
+}
diff --git a/indra/newview/llfloaterpreferenceviewadvanced.h b/indra/newview/llfloaterpreferenceviewadvanced.h
new file mode 100644
index 0000000000..4619fdaab1
--- /dev/null
+++ b/indra/newview/llfloaterpreferenceviewadvanced.h
@@ -0,0 +1,51 @@
+/**
+ * @file llfloaterpreferenceviewadvanced.h
+ * @brief floater for adjusting camera position
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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 LLFLOATERPREFERENCEVIEWADVANCED_H
+#define LLFLOATERPREFERENCEVIEWADVANCED_H
+
+#include "llcontrol.h"
+#include "llfloater.h"
+
+class LLFloaterPreferenceViewAdvanced
+: public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ LLFloaterPreferenceViewAdvanced(const LLSD& key);
+ virtual void draw();
+
+ void onCommitSettings();
+ void updateCameraControl(const LLVector3& vector);
+ void updateFocusControl(const LLVector3d& vector3d);
+
+private:
+ virtual ~LLFloaterPreferenceViewAdvanced();
+};
+
+#endif //LLFLOATERPREFERENCEVIEWADVANCED_H
+
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index ec934a4732..ec1909d02a 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -53,8 +53,6 @@
#include "llcheckboxctrl.h"
#include "llclipboard.h"
#include "llcombobox.h"
-#include "lldaycyclemanager.h"
-#include "llenvmanager.h"
#include "llestateinfomodel.h"
#include "llfilepicker.h"
#include "llfloatergodtools.h" // for send_sim_wide_deletes()
@@ -88,7 +86,6 @@
#include "llviewertexteditor.h"
#include "llviewerwindow.h"
#include "llvlcomposition.h"
-#include "llwaterparammanager.h"
#include "lltrans.h"
#include "llagentui.h"
#include "llmeshrepository.h"
@@ -100,6 +97,7 @@
#include "llpanelexperiences.h"
#include "llcorehttputil.h"
#include "llavatarnamecache.h"
+#include "llenvironment.h"
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
@@ -182,6 +180,40 @@ void unpack_request_params(
}
*/
+class LLPanelRegionEnvironment : public LLPanelEnvironmentInfo
+{
+public:
+ LLPanelRegionEnvironment();
+ virtual ~LLPanelRegionEnvironment();
+
+ virtual void refresh() override;
+
+ virtual bool isRegion() const override { return true; }
+ virtual LLParcel * getParcel() override { return nullptr; }
+ virtual bool canEdit() override { return LLEnvironment::instance().canAgentUpdateRegionEnvironment(); }
+ virtual bool isLargeEnough() override { return true; } // regions are always large enough.
+
+ bool refreshFromRegion(LLViewerRegion* region);
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override {};
+
+ virtual S32 getParcelId() override { return INVALID_PARCEL_ID; }
+
+protected:
+ static const U32 DIRTY_FLAG_OVERRIDE;
+
+ virtual void refreshFromSource() override;
+
+ bool confirmUpdateEstateEnvironment(const LLSD& notification, const LLSD& response);
+
+ void onChkAllowOverride(bool value);
+
+private:
+ bool mAllowOverrideRestore;
+ connection_t mCommitConnect;
+};
+
bool estate_dispatch_initialized = false;
@@ -196,7 +228,9 @@ LLUUID LLFloaterRegionInfo::sRequestInvoice;
LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
- : LLFloater(seed)
+ : LLFloater(seed),
+ mEnvironmentPanel(NULL),
+ mRegionChangedCallback()
{}
BOOL LLFloaterRegionInfo::postBuild()
@@ -232,10 +266,10 @@ BOOL LLFloaterRegionInfo::postBuild()
panel->buildFromFile("panel_region_terrain.xml");
mTab->addTabPanel(panel);
- panel = new LLPanelEnvironmentInfo;
- mInfoPanels.push_back(panel);
- panel->buildFromFile("panel_region_environment.xml");
- mTab->addTabPanel(panel);
+ mEnvironmentPanel = new LLPanelRegionEnvironment;
+ mEnvironmentPanel->buildFromFile("panel_region_environment.xml");
+// mEnvironmentPanel->configureForRegion();
+ mTab->addTabPanel(mEnvironmentPanel);
panel = new LLPanelRegionDebugInfo;
mInfoPanels.push_back(panel);
@@ -260,13 +294,18 @@ BOOL LLFloaterRegionInfo::postBuild()
&processEstateOwnerRequest);
// Request region info when agent region changes.
- gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));
+ mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::onRegionChanged, this));
return TRUE;
}
LLFloaterRegionInfo::~LLFloaterRegionInfo()
-{}
+{
+ if (mRegionChangedCallback.connected())
+ {
+ mRegionChangedCallback.disconnect();
+ }
+}
void LLFloaterRegionInfo::onOpen(const LLSD& key)
{
@@ -293,16 +332,26 @@ void LLFloaterRegionInfo::onClose(bool app_quitting)
}
}
+void LLFloaterRegionInfo::onRegionChanged()
+{
+ if (getVisible()) //otherwise onOpen will do request
+ {
+ requestRegionInfo();
+ }
+}
+
// static
void LLFloaterRegionInfo::requestRegionInfo()
{
- LLTabContainer* tab = getChild<LLTabContainer>("region_panels");
-
- tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
- tab->getChild<LLPanel>("Access")->setCtrlsEnabled(FALSE);
+ LLTabContainer* tab = findChild<LLTabContainer>("region_panels");
+ if (tab)
+ {
+ tab->getChild<LLPanel>("General")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Debug")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Terrain")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Estate")->setCtrlsEnabled(FALSE);
+ tab->getChild<LLPanel>("Access")->setCtrlsEnabled(FALSE);
+ }
// Must allow anyone to request the RegionInfo data
// so non-owners/non-gods can see the values.
@@ -362,13 +411,13 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
{
return;
}
-
+#if 0
// We need to re-request environment setting here,
// otherwise after we apply (send) updated region settings we won't get them back,
// so our environment won't be updated.
// This is also the way to know about externally changed region environment.
LLEnvManagerNew::instance().requestRegionSettings();
-
+#endif
LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
LLViewerRegion* region = gAgent.getRegion();
@@ -475,7 +524,12 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->setCtrlsEnabled(allow_modify);
- floater->refreshFromRegion( gAgent.getRegion() );
+ if (floater->getVisible())
+ {
+ // Note: region info also causes LLRegionInfoModel::instance().update(msg); -> requestRegion(); -> changed message
+ // we need to know env version here and in update(msg) to know when to request and when not to, when to filter 'changed'
+ floater->refreshFromRegion(gAgent.getRegion());
+ } // else will rerequest on onOpen either way
}
// static
@@ -519,6 +573,16 @@ LLPanelRegionGeneralInfo* LLFloaterRegionInfo::getPanelGeneral()
}
// static
+LLPanelRegionEnvironment* LLFloaterRegionInfo::getPanelEnvironment()
+{
+ LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
+ if (!floater) return NULL;
+ LLTabContainer* tab = floater->getChild<LLTabContainer>("region_panels");
+ LLPanelRegionEnvironment* panel = (LLPanelRegionEnvironment*)tab->getChild<LLPanel>("panel_env_info");
+ return panel;
+}
+
+// static
LLPanelRegionTerrainInfo* LLFloaterRegionInfo::getPanelRegionTerrain()
{
LLFloaterRegionInfo* floater = LLFloaterReg::getTypedInstance<LLFloaterRegionInfo>("region_info");
@@ -573,12 +637,9 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
mInfoPanels.begin(),
mInfoPanels.end(),
llbind2nd(
-#if LL_WINDOWS
- std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion),
-#else
std::mem_fun(&LLPanelRegionInfo::refreshFromRegion),
-#endif
region));
+ mEnvironmentPanel->refreshFromRegion(region);
}
// public
@@ -589,6 +650,7 @@ void LLFloaterRegionInfo::refresh()
{
(*iter)->refresh();
}
+ mEnvironmentPanel->refresh();
}
void LLFloaterRegionInfo::enableTopButtons()
@@ -2416,605 +2478,6 @@ bool LLDispatchSetEstateExperience::operator()(
return true;
}
-
-
-LLPanelEnvironmentInfo::LLPanelEnvironmentInfo()
-: mEnableEditing(false),
- mRegionSettingsRadioGroup(NULL),
- mDayCycleSettingsRadioGroup(NULL),
- mWaterPresetCombo(NULL),
- mSkyPresetCombo(NULL),
- mDayCyclePresetCombo(NULL)
-{
-}
-
-// virtual
-BOOL LLPanelEnvironmentInfo::postBuild()
-{
- mRegionSettingsRadioGroup = getChild<LLRadioGroup>("region_settings_radio_group");
- mRegionSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchRegionSettings, this));
-
- mDayCycleSettingsRadioGroup = getChild<LLRadioGroup>("sky_dayc_settings_radio_group");
- mDayCycleSettingsRadioGroup->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSwitchDayCycle, this));
-
- mWaterPresetCombo = getChild<LLComboBox>("water_settings_preset_combo");
- mWaterPresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectWaterPreset, this));
-
- mSkyPresetCombo = getChild<LLComboBox>("sky_settings_preset_combo");
- mSkyPresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectSkyPreset, this));
-
- mDayCyclePresetCombo = getChild<LLComboBox>("dayc_settings_preset_combo");
- mDayCyclePresetCombo->setCommitCallback(boost::bind(&LLPanelEnvironmentInfo::onSelectDayCycle, this));
-
- childSetCommitCallback("apply_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnApply, this), NULL);
- getChild<LLButton>("apply_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpUserPrefs, LLEnvManagerNew::getInstance()));
- childSetCommitCallback("cancel_btn", boost::bind(&LLPanelEnvironmentInfo::onBtnCancel, this), NULL);
- getChild<LLButton>("cancel_btn")->setRightMouseDownCallback(boost::bind(&LLEnvManagerNew::dumpPresets, LLEnvManagerNew::getInstance()));
-
- LLEnvManagerNew::instance().setRegionSettingsChangeCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingschange, this));
- LLEnvManagerNew::instance().setRegionSettingsAppliedCallback(boost::bind(&LLPanelEnvironmentInfo::onRegionSettingsApplied, this, _1));
-
- LLDayCycleManager::instance().setModifyCallback(boost::bind(&LLPanelEnvironmentInfo::populateDayCyclesList, this));
- LLWLParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateSkyPresetsList, this));
- LLWaterParamManager::instance().setPresetListChangeCallback(boost::bind(&LLPanelEnvironmentInfo::populateWaterPresetsList, this));
-
- return TRUE;
-}
-
-// virtual
-void LLPanelEnvironmentInfo::onOpen(const LLSD& key)
-{
- LL_DEBUGS("Windlight") << "Panel opened, refreshing" << LL_ENDL;
- refresh();
-}
-
-// virtual
-void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility)
-{
- // If hiding (user switched to another tab or closed the floater),
- // display user's preferred environment.
- if (!new_visibility)
- {
- LLEnvManagerNew::instance().usePrefs();
- }
-}
-
-// virtual
-bool LLPanelEnvironmentInfo::refreshFromRegion(LLViewerRegion* region)
-{
- LL_DEBUGS("Windlight") << "Region updated, enabling/disabling controls" << LL_ENDL;
- BOOL owner_or_god = gAgent.isGodlike() || (region && (region->getOwner() == gAgent.getID()));
- BOOL owner_or_god_or_manager = owner_or_god || (region && region->isEstateManager());
-
- // Don't refresh from region settings to avoid flicker after applying new region settings.
- mEnableEditing = owner_or_god_or_manager;
- setControlsEnabled(mEnableEditing);
-
- return LLPanelRegionInfo::refreshFromRegion(region);
-}
-
-void LLPanelEnvironmentInfo::refresh()
-{
- if(gDisconnected)
- {
- return;
- }
-
- populateWaterPresetsList();
- populateSkyPresetsList();
- populateDayCyclesList();
-
- // Init radio groups.
- const LLEnvironmentSettings& settings = LLEnvManagerNew::instance().getRegionSettings();
- const LLSD& dc = settings.getWLDayCycle();
- LLSD::Real first_frame_time = dc.size() > 0 ? dc[0][0].asReal() : 0.0f;
- const bool use_fixed_sky = dc.size() == 1 && first_frame_time < 0;
- mRegionSettingsRadioGroup->setSelectedIndex(settings.getSkyMap().size() == 0 ? 0 : 1);
- mDayCycleSettingsRadioGroup->setSelectedIndex(use_fixed_sky ? 0 : 1);
-
- setControlsEnabled(mEnableEditing);
-
- setDirty(false);
-}
-
-void LLPanelEnvironmentInfo::setControlsEnabled(bool enabled)
-{
- mRegionSettingsRadioGroup->setEnabled(enabled);
- mDayCycleSettingsRadioGroup->setEnabled(enabled);
-
- mWaterPresetCombo->setEnabled(enabled);
- mSkyPresetCombo->setEnabled(enabled);
- mDayCyclePresetCombo->setEnabled(enabled);
-
- getChildView("apply_btn")->setEnabled(enabled);
- getChildView("cancel_btn")->setEnabled(enabled);
-
- if (enabled)
- {
- // Enable/disable some controls based on currently selected radio buttons.
- bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0;
- getChild<LLView>("user_environment_settings")->setEnabled(!use_defaults);
-
- bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
- mSkyPresetCombo->setEnabled(is_fixed_sky);
- mDayCyclePresetCombo->setEnabled(!is_fixed_sky);
- }
-}
-
-void LLPanelEnvironmentInfo::setApplyProgress(bool started)
-{
- LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("progress_indicator");
-
- indicator->setVisible(started);
-
- if (started)
- {
- indicator->start();
- }
- else
- {
- indicator->stop();
- }
-}
-
-void LLPanelEnvironmentInfo::setDirty(bool dirty)
-{
- getChildView("apply_btn")->setEnabled(dirty);
- getChildView("cancel_btn")->setEnabled(dirty);
-}
-
-void LLPanelEnvironmentInfo::sendRegionSunUpdate()
-{
- LLRegionInfoModel& region_info = LLRegionInfoModel::instance();
-
- // If the region is being switched to fixed sky,
- // change the region's sun hour according to the (fixed) sun position.
- // This is needed for llGetSunDirection() LSL function to work properly (STORM-1330).
- const LLSD& sky_map = mNewRegionSettings.getSkyMap();
- bool region_use_fixed_sky = sky_map.size() == 1;
- if (region_use_fixed_sky)
- {
- LLWLParamSet param_set;
- llassert(sky_map.isMap());
- param_set.setAll(sky_map.beginMap()->second);
- F32 sun_angle = param_set.getSunAngle();
-
- LL_DEBUGS("WindlightSync") << "Old sun hour: " << region_info.mSunHour << LL_ENDL;
- // convert value range from 0..2pi to 6..30
- region_info.mSunHour = fmodf((sun_angle / F_TWO_PI) * 24.f, 24.f) + 6.f;
- }
-
- region_info.setUseFixedSun(region_use_fixed_sky);
- region_info.mUseEstateSun = !region_use_fixed_sky;
- LL_DEBUGS("WindlightSync") << "Sun hour: " << region_info.mSunHour << LL_ENDL;
-
- region_info.sendRegionTerrain(LLFloaterRegionInfo::getLastInvoice());
-}
-
-void LLPanelEnvironmentInfo::fixEstateSun()
-{
- // We don't support fixed sun estates anymore and need to fix
- // such estates for region day cycle to take effect.
- // *NOTE: Assuming that current estate settings have arrived already.
- LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
- if (estate_info.getUseFixedSun())
- {
- LL_INFOS() << "Switching estate to global sun" << LL_ENDL;
- estate_info.setUseFixedSun(false);
- estate_info.sendEstateInfo();
- }
-}
-
-void LLPanelEnvironmentInfo::populateWaterPresetsList()
-{
- mWaterPresetCombo->removeall();
-
- // If the region already has water params, add them to the list.
- const LLEnvironmentSettings& region_settings = LLEnvManagerNew::instance().getRegionSettings();
- if (region_settings.getWaterParams().size() != 0)
- {
- const std::string& region_name = gAgent.getRegion()->getName();
- mWaterPresetCombo->add(region_name, LLWLParamKey(region_name, LLEnvKey::SCOPE_REGION).toLLSD());
- mWaterPresetCombo->addSeparator();
- }
-
- std::list<std::string> user_presets, system_presets;
- LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);
-
- // Add local user presets first.
- for (std::list<std::string>::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- if (user_presets.size() > 0)
- {
- mWaterPresetCombo->addSeparator();
- }
-
- // Add local system presets.
- for (std::list<std::string>::const_iterator it = system_presets.begin(); it != system_presets.end(); ++it)
- {
- mWaterPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toLLSD());
- }
-
- // There's no way to select current preset because its name is not stored on server.
-}
-
-void LLPanelEnvironmentInfo::populateSkyPresetsList()
-{
- mSkyPresetCombo->removeall();
-
- LLWLParamManager::preset_name_list_t region_presets;
- LLWLParamManager::preset_name_list_t user_presets, sys_presets;
- LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);
-
- // Add region presets.
- std::string region_name = gAgent.getRegion() ? gAgent.getRegion()->getName() : LLTrans::getString("Unknown");
- for (LLWLParamManager::preset_name_list_t::const_iterator it = region_presets.begin(); it != region_presets.end(); ++it)
- {
- std::string preset_name = *it;
- std::string item_title = preset_name + " (" + region_name + ")";
- mSkyPresetCombo->add(item_title, LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal());
- }
-
- if (!region_presets.empty())
- {
- mSkyPresetCombo->addSeparator();
- }
-
- // Add user presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- if (!user_presets.empty())
- {
- mSkyPresetCombo->addSeparator();
- }
-
- // Add system presets.
- for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
- {
- mSkyPresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- // Select current preset.
- LLSD sky_map = LLEnvManagerNew::instance().getRegionSettings().getSkyMap();
- if (sky_map.size() == 1) // if the region is set to fixed sky
- {
- std::string preset_name = sky_map.beginMap()->first;
- mSkyPresetCombo->selectByValue(LLWLParamKey(preset_name, LLEnvKey::SCOPE_REGION).toStringVal());
- }
-}
-
-void LLPanelEnvironmentInfo::populateDayCyclesList()
-{
- mDayCyclePresetCombo->removeall();
-
- // If the region already has env. settings, add its day cycle to the list.
- const LLSD& cur_region_dc = LLEnvManagerNew::instance().getRegionSettings().getWLDayCycle();
- if (cur_region_dc.size() != 0)
- {
- LLViewerRegion* region = gAgent.getRegion();
- llassert(region != NULL);
-
- LLWLParamKey key(region->getName(), LLEnvKey::SCOPE_REGION);
- mDayCyclePresetCombo->add(region->getName(), key.toStringVal());
- mDayCyclePresetCombo->addSeparator();
- }
-
- // Add local user day cycles.
- LLDayCycleManager::preset_name_list_t user_days, sys_days;
- LLDayCycleManager::instance().getPresetNames(user_days, sys_days);
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = user_days.begin(); it != user_days.end(); ++it)
- {
- mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- if (user_days.size() > 0)
- {
- mDayCyclePresetCombo->addSeparator();
- }
-
- // Add local system day cycles.
- for (LLDayCycleManager::preset_name_list_t::const_iterator it = sys_days.begin(); it != sys_days.end(); ++it)
- {
- mDayCyclePresetCombo->add(*it, LLWLParamKey(*it, LLEnvKey::SCOPE_LOCAL).toStringVal());
- }
-
- // Current day cycle is already selected.
-}
-
-bool LLPanelEnvironmentInfo::getSelectedWaterParams(LLSD& water_params)
-{
- LLWLParamKey water_key(mWaterPresetCombo->getSelectedValue());
-
- if (water_key.scope == LLEnvKey::SCOPE_REGION)
- {
- water_params = LLEnvManagerNew::instance().getRegionSettings().getWaterParams();
- }
- else
- {
- LLWaterParamSet param_set;
- if (!LLWaterParamManager::instance().getParamSet(water_key.name, param_set))
- {
- LL_WARNS() << "Error getting water preset: " << water_key.name << LL_ENDL;
- return false;
- }
-
- water_params = param_set.getAll();
- }
-
- return true;
-}
-
-bool LLPanelEnvironmentInfo::getSelectedSkyParams(LLSD& sky_params, std::string& preset_name)
-{
- std::string preset_key(mSkyPresetCombo->getValue().asString());
- LLWLParamKey preset(preset_key);
-
- // Get the preset sky params.
- LLWLParamSet param_set;
- if (!LLWLParamManager::instance().getParamSet(preset, param_set))
- {
- LL_WARNS() << "Error getting sky params: " << preset.toLLSD() << LL_ENDL;
- return false;
- }
-
- sky_params = param_set.getAll();
- preset_name = preset.name;
- return true;
-}
-
-bool LLPanelEnvironmentInfo::getSelectedDayCycleParams(LLSD& day_cycle, LLSD& sky_map, short& scope)
-{
- std::string preset_key(mDayCyclePresetCombo->getValue().asString());
- LLWLParamKey dc(preset_key);
- LL_DEBUGS("Windlight") << "Use day cycle: " << dc.toLLSD() << LL_ENDL;
-
- if (dc.scope == LLEnvKey::SCOPE_REGION) // current region day cycle
- {
- const LLEnvironmentSettings& cur_region_settings = LLEnvManagerNew::instance().getRegionSettings();
- day_cycle = cur_region_settings.getWLDayCycle();
- sky_map = cur_region_settings.getSkyMap();
- }
- else // a local day cycle
- {
- if (!LLDayCycleManager::instance().getPreset(dc.name, day_cycle))
- {
- LL_WARNS() << "Error getting day cycle " << dc.name << LL_ENDL;
- return false;
- }
-
- // Create sky map from the day cycle.
- {
- LLWLDayCycle tmp_day;
- tmp_day.loadDayCycle(day_cycle, dc.scope);
- tmp_day.getSkyMap(sky_map);
- }
- }
-
- scope = dc.scope;
-
- return true;
-}
-void LLPanelEnvironmentInfo::onSwitchRegionSettings()
-{
- bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0;
- getChild<LLView>("user_environment_settings")->setEnabled(!use_defaults);
-
- if (use_defaults)
- {
- LLEnvManagerNew::instance().useDefaults();
- }
- else
- {
- onSelectWaterPreset();
- onSwitchDayCycle();
- }
-
- setDirty(true);
-}
-
-void LLPanelEnvironmentInfo::onSwitchDayCycle()
-{
- bool is_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
-
- mSkyPresetCombo->setEnabled(is_fixed_sky);
- mDayCyclePresetCombo->setEnabled(!is_fixed_sky);
-
- if (is_fixed_sky)
- {
- onSelectSkyPreset();
- }
- else
- {
- onSelectDayCycle();
- }
-
- setDirty(true);
-}
-
-void LLPanelEnvironmentInfo::onSelectWaterPreset()
-{
- LLSD water_params;
-
- if (getSelectedWaterParams(water_params))
- {
- LLEnvManagerNew::instance().useWaterParams(water_params);
- }
-
- setDirty(true);
-}
-
-void LLPanelEnvironmentInfo::onSelectSkyPreset()
-{
- LLSD params;
- std::string dummy;
-
- if (getSelectedSkyParams(params, dummy))
- {
- LLEnvManagerNew::instance().useSkyParams(params);
- }
-
- setDirty(true);
-}
-
-void LLPanelEnvironmentInfo::onSelectDayCycle()
-{
- LLSD day_cycle;
- LLSD sky_map; // unused
- short scope;
-
- if (getSelectedDayCycleParams(day_cycle, sky_map, scope))
- {
- LLEnvManagerNew::instance().useDayCycleParams(day_cycle, (LLEnvKey::EScope) scope);
- }
-
- setDirty(true);
-}
-
-void LLPanelEnvironmentInfo::onBtnApply()
-{
- const bool use_defaults = mRegionSettingsRadioGroup->getSelectedIndex() == 0;
- const bool use_fixed_sky = mDayCycleSettingsRadioGroup->getSelectedIndex() == 0;
-
- LLSD day_cycle;
- LLSD sky_map;
- LLSD water_params;
-
- if (use_defaults)
- {
- // settings will be empty
- LL_DEBUGS("Windlight") << "Defaults" << LL_ENDL;
- }
- else // use custom region settings
- {
- if (use_fixed_sky)
- {
- LL_DEBUGS("Windlight") << "Use fixed sky" << LL_ENDL;
-
- // Get selected sky params.
- LLSD params;
- std::string preset_name;
- if (!getSelectedSkyParams(params, preset_name))
- {
- return;
- }
-
- // Create a day cycle consisting of a single sky preset.
- LLSD key(LLSD::emptyArray());
- key.append(-1.0f); // indicate that user preference is actually fixed sky, not a day cycle
- key.append(preset_name);
- day_cycle.append(key);
-
- // Create a sky map consisting of only the sky preset.
- std::map<LLWLParamKey, LLWLParamSet> refs;
- LLWLParamSet param_set;
- param_set.setAll(params);
- refs[LLWLParamKey(preset_name, LLEnvKey::SCOPE_LOCAL)] = param_set; // scope doesn't matter here
- sky_map = LLWLParamManager::createSkyMap(refs);
- }
- else // use day cycle
- {
- LL_DEBUGS("Windlight") << "Use day cycle" << LL_ENDL;
-
- short scope; // unused
- if (!getSelectedDayCycleParams(day_cycle, sky_map, scope))
- {
- return;
- }
-
- // If it's a special single-preset day cycle meaning using a fixed sky,
- // reset the frame time to a non-negative value,
- // so that the region setting is displayed in the floater as
- // a day cycle, not a preset. (STORM-1289)
- if (day_cycle.size() == 1 && day_cycle[0][0].asReal() < 0.0f)
- {
- LL_DEBUGS("Windlight") << "Fixing negative time" << LL_ENDL;
- day_cycle[0][0] = 0.0f;
- }
- }
-
- // Get water params.
- if (!getSelectedWaterParams(water_params))
- {
- // *TODO: show a notification?
- return;
- }
- }
-
- // Send settings apply request.
- LLEnvironmentSettings new_region_settings;
- new_region_settings.saveParams(day_cycle, sky_map, water_params, 0.0f);
- if (!LLEnvManagerNew::instance().sendRegionSettings(new_region_settings))
- {
- LL_WARNS() << "Error applying region environment settings" << LL_ENDL;
- return;
- }
-
- // When the settings get applied, we'll also send the region sun position update.
- // To determine the sun angle we're going to need the new settings.
- mNewRegionSettings = new_region_settings;
-
- // Start spinning the progress indicator.
- setApplyProgress(true);
-}
-
-void LLPanelEnvironmentInfo::onBtnCancel()
-{
- // Reload last saved region settings.
- refresh();
-
- // Apply them.
- LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
- const LLEnvironmentSettings& cur_settings = env_mgr.getRegionSettings();
- const LLSD& region_day_cycle = cur_settings.getWLDayCycle();
- const LLSD& region_water = cur_settings.getWaterParams();
- env_mgr.useWaterParams(region_water);
- env_mgr.useDayCycleParams(region_day_cycle, LLEnvKey::SCOPE_REGION);
-}
-
-void LLPanelEnvironmentInfo::onRegionSettingschange()
-{
- LL_DEBUGS("Windlight") << "Region settings changed, refreshing" << LL_ENDL;
- refresh();
-
- // Stop applying progress indicator (it may be running if it's us who initiated settings update).
- setApplyProgress(false);
-}
-
-void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok)
-{
- // If applying new settings has failed, stop the indicator right away.
- // Otherwise it will be stopped when we receive the updated settings from server.
- if (ok)
- {
- // Set the region sun phase/flags according to the chosen new preferences.
- //
- // If we do this earlier we may get jerky transition from fixed sky to a day cycle (STORM-1481).
- // That is caused by the simulator re-sending the region info, which in turn makes us
- // re-request and display old region environment settings while the new ones haven't been applied yet.
- sendRegionSunUpdate();
-
- // Switch estate to not using fixed sun for the region day cycle to work properly (STORM-1506).
- fixEstateSun();
- }
- else
- {
- setApplyProgress(false);
-
- // We need to re-request environment setting here,
- // otherwise our subsequent attempts to change region settings will fail with the following error:
- // "Unable to update environment settings because the last update your viewer saw was not the same
- // as the last update sent from the simulator. Try sending your update again, and if this
- // does not work, try leaving and returning to the region."
- LLEnvManagerNew::instance().requestRegionSettings();
- }
-}
-
BOOL LLPanelRegionExperiences::postBuild()
{
mAllowed = setupList("panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE);
@@ -4239,3 +3702,152 @@ bool LLPanelEstateAccess::refreshFromRegion(LLViewerRegion* region)
return LLPanelRegionInfo::refreshFromRegion(region);
}
+//=========================================================================
+const U32 LLPanelRegionEnvironment::DIRTY_FLAG_OVERRIDE(0x01 << 4);
+
+LLPanelRegionEnvironment::LLPanelRegionEnvironment():
+ LLPanelEnvironmentInfo(),
+ mAllowOverrideRestore(false)
+{
+}
+
+LLPanelRegionEnvironment::~LLPanelRegionEnvironment()
+{
+ if (mCommitConnect.connected())
+ mCommitConnect.disconnect();
+}
+
+BOOL LLPanelRegionEnvironment::postBuild()
+{
+ LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+ if (!LLPanelEnvironmentInfo::postBuild())
+ return FALSE;
+
+ getChild<LLUICtrl>(BTN_USEDEFAULT)->setLabelArg("[USEDEFAULT]", getString(STR_LABEL_USEDEFAULT));
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setVisible(TRUE);
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(TRUE);
+
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setCommitCallback([this](LLUICtrl *, const LLSD &value){ onChkAllowOverride(value.asBoolean()); });
+
+ mCommitConnect = estate_info.setCommitCallback(boost::bind(&LLPanelRegionEnvironment::refreshFromEstate, this));
+ return TRUE;
+}
+
+
+void LLPanelRegionEnvironment::refresh()
+{
+ commitDayLenOffsetChanges(false); // commit unsaved changes if any
+
+ if (!mCurrentEnvironment)
+ {
+ if (mCurEnvVersion <= INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ refreshFromSource(); // will immediately set mCurEnvVersion
+ } // else - already requesting
+ return;
+ }
+
+ LLPanelEnvironmentInfo::refresh();
+
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setValue(mAllowOverride);
+}
+
+bool LLPanelRegionEnvironment::refreshFromRegion(LLViewerRegion* region)
+{
+ if (!region)
+ {
+ setNoSelection(true);
+ setControlsEnabled(false);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ getChild<LLUICtrl>("region_text")->setValue(LLSD(""));
+ }
+ else
+ {
+ getChild<LLUICtrl>("region_text")->setValue(LLSD(region->getName()));
+ }
+ setNoSelection(false);
+
+ if (gAgent.getRegion()->getRegionID() != region->getRegionID())
+ {
+ setCrossRegion(true);
+ mCurEnvVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
+ }
+ setCrossRegion(false);
+
+ refreshFromSource();
+ return true;
+}
+
+void LLPanelRegionEnvironment::refreshFromSource()
+{
+ LL_DEBUGS("ENVIRONMENT") << "Requesting environment for region, known version " << mCurEnvVersion << LL_ENDL;
+ LLHandle<LLPanel> that_h = getHandle();
+
+ if (mCurEnvVersion < UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // to mark as requesting
+ mCurEnvVersion = UNSET_PARCEL_ENVIRONMENT_VERSION;
+ }
+
+ LLEnvironment::instance().requestRegion(
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+
+ setControlsEnabled(false);
+}
+
+bool LLPanelRegionEnvironment::confirmUpdateEstateEnvironment(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ switch (option)
+ {
+ case 0:
+ {
+ LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+ // update model
+ estate_info.setAllowEnvironmentOverride(mAllowOverride);
+ // send the update to sim
+ estate_info.sendEstateInfo();
+ clearDirtyFlag(DIRTY_FLAG_OVERRIDE);
+ }
+ break;
+
+ case 1:
+ mAllowOverride = mAllowOverrideRestore;
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setValue(mAllowOverride);
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void LLPanelRegionEnvironment::onChkAllowOverride(bool value)
+{
+ setDirtyFlag(DIRTY_FLAG_OVERRIDE);
+ mAllowOverrideRestore = mAllowOverride;
+ mAllowOverride = value;
+
+
+ std::string notification("EstateParcelEnvironmentOverride");
+ if (LLPanelEstateInfo::isLindenEstate())
+ notification = "ChangeLindenEstate";
+
+ LLSD args;
+ args["ESTATENAME"] = LLEstateInfoModel::instance().getName();
+ LLNotification::Params params(notification);
+ params.substitutions(args);
+ params.functor.function([this](const LLSD& notification, const LLSD& response) { confirmUpdateEstateEnvironment(notification, response); });
+
+ if (!value || LLPanelEstateInfo::isLindenEstate())
+ { // warn if turning off or a Linden Estate
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+
+}
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 5d0f5fc6fc..75d0c3ea5c 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -35,8 +35,8 @@
#include "llhost.h"
#include "llpanel.h"
#include "llextendedstatus.h"
+#include "llpanelenvironment.h"
-#include "llenvmanager.h" // for LLEnvironmentSettings
#include "lleventcoro.h"
class LLAvatarName;
@@ -66,13 +66,9 @@ class LLPanelExperienceListEditor;
class LLPanelExperiences;
class LLPanelRegionExperiences;
class LLPanelEstateAccess;
+class LLPanelRegionEnvironment;
class LLEventTimer;
-class LLEnvironmentSettings;
-class LLWLParamManager;
-class LLWaterParamManager;
-class LLWLParamSet;
-class LLWaterParamSet;
class LLFloaterRegionInfo : public LLFloater
{
@@ -100,10 +96,12 @@ public:
static LLPanelRegionTerrainInfo* getPanelRegionTerrain();
static LLPanelRegionExperiences* getPanelExperiences();
static LLPanelRegionGeneralInfo* getPanelGeneral();
+ static LLPanelRegionEnvironment* getPanelEnvironment();
// from LLPanel
virtual void refresh();
+ void onRegionChanged();
void requestRegionInfo();
void requestMeshRezInfo();
void enableTopButtons();
@@ -124,12 +122,13 @@ protected:
LLTabContainer* mTab;
typedef std::vector<LLPanelRegionInfo*> info_panels_t;
info_panels_t mInfoPanels;
- //static S32 sRequestSerial; // serial # of last EstateOwnerRequest
+ LLPanelRegionEnvironment *mEnvironmentPanel;
+ //static S32 sRequestSerial; // serial # of last EstateOwnerRequest
static LLUUID sRequestInvoice;
private:
- LLAgent::god_level_change_slot_t mGodLevelChangeSlot;
-
+ LLAgent::god_level_change_slot_t mGodLevelChangeSlot;
+ boost::signals2::connection mRegionChangedCallback;
};
@@ -398,69 +397,10 @@ protected:
/////////////////////////////////////////////////////////////////////////////
-class LLPanelEnvironmentInfo : public LLPanelRegionInfo
-{
- LOG_CLASS(LLPanelEnvironmentInfo);
-
-public:
- LLPanelEnvironmentInfo();
-
- // LLPanel
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
-
- // LLView
- /*virtual*/ void onVisibilityChange(BOOL new_visibility);
-
- // LLPanelRegionInfo
- /*virtual*/ bool refreshFromRegion(LLViewerRegion* region);
-
-private:
- void refresh();
- void setControlsEnabled(bool enabled);
- void setApplyProgress(bool started);
- void setDirty(bool dirty);
-
- void sendRegionSunUpdate();
- void fixEstateSun();
-
- void populateWaterPresetsList();
- void populateSkyPresetsList();
- void populateDayCyclesList();
-
- bool getSelectedWaterParams(LLSD& water_params);
- bool getSelectedSkyParams(LLSD& sky_params, std::string& preset_name);
- bool getSelectedDayCycleParams(LLSD& day_cycle, LLSD& sky_map, short& scope);
-
- void onSwitchRegionSettings();
- void onSwitchDayCycle();
-
- void onSelectWaterPreset();
- void onSelectSkyPreset();
- void onSelectDayCycle();
-
- void onBtnApply();
- void onBtnCancel();
-
- void onRegionSettingschange();
- void onRegionSettingsApplied(bool ok);
-
- /// New environment settings that are being applied to the region.
- LLEnvironmentSettings mNewRegionSettings;
-
- bool mEnableEditing;
-
- LLRadioGroup* mRegionSettingsRadioGroup;
- LLRadioGroup* mDayCycleSettingsRadioGroup;
-
- LLComboBox* mWaterPresetCombo;
- LLComboBox* mSkyPresetCombo;
- LLComboBox* mDayCyclePresetCombo;
-};
class LLPanelRegionExperiences : public LLPanelRegionInfo
{
- LOG_CLASS(LLPanelEnvironmentInfo);
+ LOG_CLASS(LLPanelRegionExperiences);
public:
LLPanelRegionExperiences(){}
@@ -493,7 +433,7 @@ private:
class LLPanelEstateAccess : public LLPanelRegionInfo
{
- LOG_CLASS(LLPanelEnvironmentInfo);
+ LOG_CLASS(LLPanelEstateAccess);
public:
LLPanelEstateAccess();
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 960fd9620d..a30c73768d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -102,7 +102,6 @@ public:
virtual LLSD prepareUpload();
virtual LLSD generatePostBody();
- virtual S32 getEconomyUploadCost();
virtual LLUUID finishUpload(LLSD &result);
virtual bool showInventoryPanel() const { return false; }
@@ -129,11 +128,6 @@ LLSD LLARScreenShotUploader::generatePostBody()
return mReport;
}
-S32 LLARScreenShotUploader::getEconomyUploadCost()
-{ // Abuse report screen shots do not cost anything to upload.
- return 0;
-}
-
LLUUID LLARScreenShotUploader::finishUpload(LLSD &result)
{
/* *TODO$: Report success or failure. Carried over from previous todo on responder*/
@@ -752,9 +746,6 @@ LLSD LLFloaterReporter::gatherReport()
const char* platform = "Mac";
#elif LL_LINUX
const char* platform = "Lnx";
-#elif LL_SOLARIS
- const char* platform = "Sol";
- const char* short_platform = "O:S";
#else
const char* platform = "???";
#endif
@@ -771,7 +762,7 @@ LLSD LLFloaterReporter::gatherReport()
std::ostringstream details;
- details << "V" << LLVersionInfo::getVersion() << std::endl << std::endl; // client version moved to body of email for abuse reports
+ details << "V" << LLVersionInfo::instance().getVersion() << std::endl << std::endl; // client version moved to body of email for abuse reports
std::string object_name = getChild<LLUICtrl>("object_name")->getValue().asString();
if (!object_name.empty() && !mOwnerName.empty())
@@ -789,7 +780,7 @@ LLSD LLFloaterReporter::gatherReport()
std::string version_string;
version_string = llformat(
"%s %s %s %s %s",
- LLVersionInfo::getShortVersion().c_str(),
+ LLVersionInfo::instance().getShortVersion().c_str(),
platform,
gSysCPU.getFamily().c_str(),
gGLManager.mGLRenderer.c_str(),
@@ -936,7 +927,7 @@ void LLFloaterReporter::takeNewSnapshot()
// Take a screenshot, but don't draw this floater.
setVisible(FALSE);
- if( !gViewerWindow->rawSnapshot(mImageRaw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE))
+ if (!gViewerWindow->rawSnapshot(mImageRaw,IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE /*UI*/, TRUE, FALSE))
{
LL_WARNS() << "Unable to take screenshot" << LL_ENDL;
setVisible(TRUE);
diff --git a/indra/newview/llfloatersavecamerapreset.cpp b/indra/newview/llfloatersavecamerapreset.cpp
new file mode 100644
index 0000000000..11809f9c82
--- /dev/null
+++ b/indra/newview/llfloatersavecamerapreset.cpp
@@ -0,0 +1,172 @@
+/**
+ * @file llfloatersavecamerapreset.cpp
+ * @brief Floater to save a camera preset
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersavecamerapreset.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llfloaterpreference.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpresetsmanager.h"
+#include "llradiogroup.h"
+#include "lltrans.h"
+#include "llvoavatarself.h"
+
+LLFloaterSaveCameraPreset::LLFloaterSaveCameraPreset(const LLSD &key)
+ : LLModalDialog(key)
+{
+}
+
+// virtual
+BOOL LLFloaterSaveCameraPreset::postBuild()
+{
+ mPresetCombo = getChild<LLComboBox>("preset_combo");
+
+ mNameEditor = getChild<LLLineEditor>("preset_txt_editor");
+ mNameEditor->setKeystrokeCallback(boost::bind(&LLFloaterSaveCameraPreset::onPresetNameEdited, this), NULL);
+
+ mSaveButton = getChild<LLButton>("save");
+ mSaveButton->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onBtnSave, this));
+
+ mSaveRadioGroup = getChild<LLRadioGroup>("radio_save_preset");
+ mSaveRadioGroup->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onSwitchSaveReplace, this));
+
+ getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSaveCameraPreset::onBtnCancel, this));
+
+ LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSaveCameraPreset::onPresetsListChange, this));
+
+ return TRUE;
+}
+
+void LLFloaterSaveCameraPreset::onPresetNameEdited()
+{
+ if (mSaveRadioGroup->getSelectedIndex() == 0)
+ {
+ // Disable saving a preset having empty name.
+ std::string name = mNameEditor->getValue();
+ mSaveButton->setEnabled(!name.empty());
+ }
+}
+
+void LLFloaterSaveCameraPreset::onOpen(const LLSD& key)
+{
+ LLModalDialog::onOpen(key);
+ S32 index = 0;
+ if (key.has("index"))
+ {
+ index = key["index"].asInteger();
+ }
+
+ LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, DEFAULT_BOTTOM);
+
+ mSaveRadioGroup->setSelectedIndex(index);
+ onPresetNameEdited();
+ onSwitchSaveReplace();
+}
+
+void LLFloaterSaveCameraPreset::onBtnSave()
+{
+ bool is_saving_new = mSaveRadioGroup->getSelectedIndex() == 0;
+ std::string name = is_saving_new ? mNameEditor->getText() : mPresetCombo->getSimple();
+
+ if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT))
+ {
+ LLNotificationsUtil::add("DefaultPresetNotSaved");
+ }
+ else
+ {
+ if (isAgentAvatarValid() && gAgentAvatarp->getParent())
+ {
+ gSavedSettings.setLLSD("AvatarSitRotation", gAgent.getFrameAgent().getQuaternion().getValue());
+ }
+ if (gAgentCamera.isJoystickCameraUsed())
+ {
+ gSavedSettings.setVector3("CameraOffsetRearView", gAgentCamera.getCurrentCameraOffset());
+ gSavedSettings.setVector3d("FocusOffsetRearView", gAgentCamera.getCurrentFocusOffset());
+ gAgentCamera.resetCameraZoomFraction();
+ gAgentCamera.setFocusOnAvatar(TRUE, TRUE, FALSE);
+ }
+ else
+ {
+ LLVector3 camera_offset = gSavedSettings.getVector3("CameraOffsetRearView") * gAgentCamera.getCurrentCameraZoomFraction();
+ gSavedSettings.setVector3("CameraOffsetRearView", camera_offset);
+ gAgentCamera.resetCameraZoomFraction();
+ }
+ if (is_saving_new)
+ {
+ std::list<std::string> preset_names;
+ LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_CAMERA, preset_names, DEFAULT_HIDE);
+ if (std::find(preset_names.begin(), preset_names.end(), name) != preset_names.end())
+ {
+ LLSD args;
+ args["NAME"] = name;
+ LLNotificationsUtil::add("PresetAlreadyExists", args);
+ return;
+ }
+ }
+ if (!LLPresetsManager::getInstance()->savePreset(PRESETS_CAMERA, name))
+ {
+ LLSD args;
+ args["NAME"] = name;
+ LLNotificationsUtil::add("PresetNotSaved", args);
+ }
+ }
+
+ closeFloater();
+}
+
+void LLFloaterSaveCameraPreset::onPresetsListChange()
+{
+ LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, DEFAULT_BOTTOM);
+}
+
+void LLFloaterSaveCameraPreset::onBtnCancel()
+{
+ closeFloater();
+}
+
+void LLFloaterSaveCameraPreset::onSwitchSaveReplace()
+{
+ bool is_saving_new = mSaveRadioGroup->getSelectedIndex() == 0;
+ std::string label = is_saving_new ? getString("btn_label_save") : getString("btn_label_replace");
+ mSaveButton->setLabel(label);
+ mNameEditor->setEnabled(is_saving_new);
+ mPresetCombo->setEnabled(!is_saving_new);
+ if (is_saving_new)
+ {
+ onPresetNameEdited();
+ }
+ else
+ {
+ mSaveButton->setEnabled(true);
+ }
+}
diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloatersavecamerapreset.h
index 1211505273..282f213438 100644
--- a/indra/newview/llfloaterdeleteenvpreset.h
+++ b/indra/newview/llfloatersavecamerapreset.h
@@ -1,10 +1,11 @@
/**
- * @file llfloaterdeleteenvpreset.h
- * @brief Floater to delete a water / sky / day cycle preset.
+ * @file llfloatersavecamerapreset.h
+ * @brief Floater to save a camera preset
+
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2020, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,39 +25,36 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLFLOATERDELETEENVPRESET_H
-#define LL_LLFLOATERDELETEENVPRESET_H
+#ifndef LL_LLFLOATERSAVECAMERAPRESET_H
+#define LL_LLFLOATERSAVECAMERAPRESET_H
-#include "llfloater.h"
+#include "llmodaldialog.h"
class LLComboBox;
+class LLRadioGroup;
+class LLLineEditor;
-class LLFloaterDeleteEnvPreset : public LLFloater
+class LLFloaterSaveCameraPreset : public LLModalDialog
{
- LOG_CLASS(LLFloaterDeleteEnvPreset);
public:
- LLFloaterDeleteEnvPreset(const LLSD &key);
+ LLFloaterSaveCameraPreset(const LLSD &key);
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
- void onBtnDelete();
+ void onBtnSave();
void onBtnCancel();
+ void onSwitchSaveReplace();
private:
- void populatePresetsList();
- void populateWaterPresetsList();
- void populateSkyPresetsList();
- void populateDayCyclesList();
-
- void postPopulate();
-
- void onDeleteDayCycleConfirmation();
- void onDeleteSkyPresetConfirmation();
- void onDeleteWaterPresetConfirmation();
+ LLRadioGroup* mSaveRadioGroup;
+ LLLineEditor* mNameEditor;
+ LLComboBox* mPresetCombo;
+ LLButton* mSaveButton;
- LLComboBox* mPresetCombo;
+ void onPresetsListChange();
+ void onPresetNameEdited();
};
-#endif // LL_LLFLOATERDELETEENVPRESET_H
+#endif // LL_LLFLOATERSAVECAMERAPRESET_H
diff --git a/indra/newview/llfloatersaveprefpreset.cpp b/indra/newview/llfloatersaveprefpreset.cpp
index 684778c93a..dd47d02bfa 100644
--- a/indra/newview/llfloatersaveprefpreset.cpp
+++ b/indra/newview/llfloatersaveprefpreset.cpp
@@ -1,6 +1,6 @@
/**
* @file llfloatersaveprefpreset.cpp
- * @brief Floater to save a graphics / camera preset
+ * @brief Floater to save a graphics preset
*
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -37,24 +37,27 @@
#include "lltrans.h"
LLFloaterSavePrefPreset::LLFloaterSavePrefPreset(const LLSD &key)
-: LLFloater(key)
+ : LLFloater(key)
{
}
// virtual
BOOL LLFloaterSavePrefPreset::postBuild()
-{ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+{
+ LLFloaterPreference* preferences = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (preferences)
{
preferences->addDependentFloater(this);
}
+
getChild<LLComboBox>("preset_combo")->setTextEntryCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
getChild<LLComboBox>("preset_combo")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetNameEdited, this));
getChild<LLButton>("save")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnSave, this));
+
getChild<LLButton>("cancel")->setCommitCallback(boost::bind(&LLFloaterSavePrefPreset::onBtnCancel, this));
LLPresetsManager::instance().setPresetListChangeCallback(boost::bind(&LLFloaterSavePrefPreset::onPresetsListChange, this));
-
+
mSaveButton = getChild<LLButton>("save");
mPresetCombo = getChild<LLComboBox>("preset_combo");
@@ -73,10 +76,6 @@ void LLFloaterSavePrefPreset::onOpen(const LLSD& key)
{
mSubdirectory = key.asString();
- std::string floater_title = getString(std::string("title_") + mSubdirectory);
-
- setTitle(floater_title);
-
EDefaultOptions option = DEFAULT_HIDE;
LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, mPresetCombo, option);
@@ -87,7 +86,10 @@ void LLFloaterSavePrefPreset::onBtnSave()
{
std::string name = mPresetCombo->getSimple();
- if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT))
+ std::string upper_name(name);
+ LLStringUtil::toUpper(upper_name);
+
+ if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (upper_name == PRESETS_DEFAULT_UPPER))
{
LLNotificationsUtil::add("DefaultPresetNotSaved");
}
diff --git a/indra/newview/llfloatersaveprefpreset.h b/indra/newview/llfloatersaveprefpreset.h
index 09a87b8c62..ae58180e7f 100644
--- a/indra/newview/llfloatersaveprefpreset.h
+++ b/indra/newview/llfloatersaveprefpreset.h
@@ -1,6 +1,6 @@
/**
* @file llfloatersaveprefpreset.h
- * @brief Floater to save a graphics / camera preset
+ * @brief Floater to save a graphics preset
*
* $LicenseInfo:firstyear=2014&license=viewerlgpl$
@@ -45,6 +45,7 @@ public:
void onBtnCancel();
private:
+
LLComboBox* mPresetCombo;
LLButton* mSaveButton;
diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index fb202b4c40..186994c857 100644
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
@@ -111,6 +111,7 @@ void LLFloaterSettingsDebug::onCommitSettings()
LLVector3 vector;
LLVector3d vectord;
+ LLQuaternion quat;
LLRect rect;
LLColor4 col4;
LLColor3 col3;
@@ -146,6 +147,13 @@ void LLFloaterSettingsDebug::onCommitSettings()
vectord.mdV[VZ] = getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
controlp->set(vectord.getValue());
break;
+ case TYPE_QUAT:
+ quat.mQ[VX] = getChild<LLUICtrl>("val_spinner_1")->getValue().asReal();
+ quat.mQ[VY] = getChild<LLUICtrl>("val_spinner_2")->getValue().asReal();
+ quat.mQ[VZ] = getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
+ quat.mQ[VS] = getChild<LLUICtrl>("val_spinner_4")->getValue().asReal();;
+ controlp->set(quat.getValue());
+ break;
case TYPE_RECT:
rect.mLeft = getChild<LLUICtrl>("val_spinner_1")->getValue().asInteger();
rect.mRight = getChild<LLUICtrl>("val_spinner_2")->getValue().asInteger();
@@ -351,6 +359,40 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
}
break;
}
+ case TYPE_QUAT:
+ {
+ LLQuaternion q;
+ q.setValue(sd);
+ spinner1->setVisible(TRUE);
+ spinner1->setLabel(std::string("X"));
+ spinner2->setVisible(TRUE);
+ spinner2->setLabel(std::string("Y"));
+ spinner3->setVisible(TRUE);
+ spinner3->setLabel(std::string("Z"));
+ spinner4->setVisible(TRUE);
+ spinner4->setLabel(std::string("S"));
+ if (!spinner1->hasFocus())
+ {
+ spinner1->setPrecision(4);
+ spinner1->setValue(q.mQ[VX]);
+ }
+ if (!spinner2->hasFocus())
+ {
+ spinner2->setPrecision(4);
+ spinner2->setValue(q.mQ[VY]);
+ }
+ if (!spinner3->hasFocus())
+ {
+ spinner3->setPrecision(4);
+ spinner3->setValue(q.mQ[VZ]);
+ }
+ if (!spinner4->hasFocus())
+ {
+ spinner4->setPrecision(4);
+ spinner4->setValue(q.mQ[VS]);
+ }
+ break;
+ }
case TYPE_RECT:
{
LLRect r;
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 64ddeff1b0..dd7ce40e97 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -60,7 +60,7 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
{
LLPanelOutfitEdit* panel_outfit_edit =
- dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
+ dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::findPanel("appearance", "panel_outfit_edit"));
if (panel_outfit_edit)
{
LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
@@ -145,3 +145,15 @@ LLPanel* LLFloaterSidePanelContainer::getPanel(const std::string& floater_name,
return NULL;
}
+
+LLPanel* LLFloaterSidePanelContainer::findPanel(const std::string& floater_name, const std::string& panel_name)
+{
+ LLFloaterSidePanelContainer* floaterp = LLFloaterReg::findTypedInstance<LLFloaterSidePanelContainer>(floater_name);
+
+ if (floaterp)
+ {
+ return floaterp->findChild<LLPanel>(panel_name, true);
+ }
+
+ return NULL;
+}
diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h
index 635514e26c..20baf28184 100644
--- a/indra/newview/llfloatersidepanelcontainer.h
+++ b/indra/newview/llfloatersidepanelcontainer.h
@@ -62,6 +62,8 @@ public:
static void showPanel(const std::string& floater_name, const std::string& panel_name, const LLSD& key);
static LLPanel* getPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
+
+ static LLPanel* findPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
/**
* Gets the panel of given type T (doesn't show it or do anything else with it).
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index bcba14d63d..8221b0a637 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -34,6 +34,7 @@
class LLSpinCtrl;
class LLSnapshotLivePreview;
+class LLToolset;
class LLFloaterSnapshotBase : public LLFloater
{
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index fce945df6c..97e99297cf 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -33,7 +33,6 @@
#define LL_LLFLOATERWORLDMAP_H
#include "llfloater.h"
-#include "llhudtext.h"
#include "llmapimagetype.h"
#include "lltracker.h"
#include "llslurl.h"
diff --git a/indra/newview/llflyoutcombobtn.cpp b/indra/newview/llflyoutcombobtn.cpp
new file mode 100644
index 0000000000..e4f1d9fcaa
--- /dev/null
+++ b/indra/newview/llflyoutcombobtn.cpp
@@ -0,0 +1,162 @@
+/**
+ * @file llflyoutcombobtn.cpp
+ * @brief Represents outfit save/save as combo button.
+ *
+ * $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 "llflyoutcombobtn.h"
+#include "llviewermenu.h"
+
+LLFlyoutComboBtnCtrl::LLFlyoutComboBtnCtrl(LLPanel* parent,
+ const std::string &action_button,
+ const std::string &flyout_button,
+ const std::string &menu_file,
+ bool apply_immediately) :
+ mParent(parent),
+ mActionButton(action_button),
+ mFlyoutButton(flyout_button),
+ mApplyImmediately(apply_immediately)
+{
+ // register action mapping before creating menu
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar;
+ save_registar.add("FlyoutCombo.Button.Action", [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutItemSelected(ctrl, data); });
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enabled_rgistar;
+ enabled_rgistar.add("FlyoutCombo.Button.Check", [this](LLUICtrl *ctrl, const LLSD &data) { return onFlyoutItemCheck(ctrl, data); });
+
+ mParent->childSetAction(flyout_button, [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutButton(ctrl, data); });
+ mParent->childSetAction(action_button, [this](LLUICtrl *ctrl, const LLSD &data) { onFlyoutAction(ctrl, data); });
+
+ mFlyoutMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu> (menu_file, gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+
+ // select the first item in the list.
+ setSelectedItem(0);
+}
+
+void LLFlyoutComboBtnCtrl::setAction(LLUICtrl::commit_callback_t cb)
+{
+ mActionSignal.connect(cb);
+}
+
+
+U32 LLFlyoutComboBtnCtrl::getItemCount()
+{
+ return mFlyoutMenu->getItemCount();
+}
+
+void LLFlyoutComboBtnCtrl::setSelectedItem(S32 itemno)
+{
+ LLMenuItemGL *pitem = mFlyoutMenu->getItem(itemno);
+ setSelectedItem(pitem);
+}
+
+void LLFlyoutComboBtnCtrl::setSelectedItem(const std::string &item)
+{
+ LLMenuItemGL *pitem = mFlyoutMenu->getChild<LLMenuItemGL>(item, false);
+ setSelectedItem(pitem);
+}
+
+void LLFlyoutComboBtnCtrl::setSelectedItem(LLMenuItemGL *pitem)
+{
+ if (!pitem)
+ {
+ LL_WARNS("INTERFACE") << "NULL item selected" << LL_ENDL;
+ return;
+ }
+
+ mSelectedName = pitem->getName();
+
+ LLButton *action_button = mParent->getChild<LLButton>(mActionButton);
+ action_button->setEnabled(pitem->getEnabled());
+ action_button->setLabel(pitem->getLabel());
+}
+
+void LLFlyoutComboBtnCtrl::setMenuItemEnabled(const std::string& item, bool enabled)
+{
+ mFlyoutMenu->setItemEnabled(item, enabled);
+ if (item == mSelectedName)
+ {
+ mParent->getChildView(mActionButton)->setEnabled(enabled);
+ }
+}
+
+void LLFlyoutComboBtnCtrl::setShownBtnEnabled(bool enabled)
+{
+ mParent->getChildView(mActionButton)->setEnabled(enabled);
+}
+
+void LLFlyoutComboBtnCtrl::setMenuItemVisible(const std::string &item, bool visible)
+{
+ mFlyoutMenu->setItemVisible(item, visible);
+}
+
+
+void LLFlyoutComboBtnCtrl::setMenuItemLabel(const std::string &item, const std::string &label)
+{
+ mFlyoutMenu->setItemLabel(item, label);
+}
+
+void LLFlyoutComboBtnCtrl::onFlyoutButton(LLUICtrl *ctrl, const LLSD &data)
+{
+ S32 x, y;
+ LLUI::getInstance()->getMousePositionLocal(mParent, &x, &y);
+
+ mFlyoutMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(mParent, mFlyoutMenu, x, y);
+}
+
+void LLFlyoutComboBtnCtrl::onFlyoutItemSelected(LLUICtrl *ctrl, const LLSD &data)
+{
+ LLMenuItemGL *pmenuitem = static_cast<LLMenuItemGL*>(ctrl);
+ setSelectedItem(pmenuitem);
+
+ if (mApplyImmediately)
+ {
+ onFlyoutAction(pmenuitem, data);
+ }
+}
+
+bool LLFlyoutComboBtnCtrl::onFlyoutItemCheck(LLUICtrl *ctrl, const LLSD &data)
+{
+ if (mApplyImmediately)
+ {
+ return false;
+ }
+ else
+ {
+ LLMenuItemGL *pmenuitem = static_cast<LLMenuItemGL*>(ctrl);
+
+ return pmenuitem->getName() == mSelectedName;
+ }
+}
+
+void LLFlyoutComboBtnCtrl::onFlyoutAction(LLUICtrl *ctrl, const LLSD &data)
+{
+ LLMenuItemGL *pmenuitem = mFlyoutMenu->getChild<LLMenuItemGL>(mSelectedName);
+
+ if (!mActionSignal.empty())
+ mActionSignal(pmenuitem, data);
+}
+
diff --git a/indra/newview/llflyoutcombobtn.h b/indra/newview/llflyoutcombobtn.h
new file mode 100644
index 0000000000..e41cd0cecb
--- /dev/null
+++ b/indra/newview/llflyoutcombobtn.h
@@ -0,0 +1,76 @@
+/**
+ * @file llsaveoutfitcombobtn.h
+ * @brief Represents outfit save/save as combo button.
+ *
+ * $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 LL_LLFLYOUTCOMBOBTN_H
+#define LL_LLFLYOUTCOMBOBTN_H
+
+/*TODO: Make this button generic */
+
+class LLButton;
+
+#include "lltoggleablemenu.h"
+
+class LLFlyoutComboBtnCtrl
+{
+ LOG_CLASS(LLFlyoutComboBtnCtrl);
+public:
+ LLFlyoutComboBtnCtrl(LLPanel* parent,
+ const std::string &action_button,
+ const std::string &flyout_button,
+ const std::string &menu_file,
+ bool apply_immediately = true);
+
+ void setMenuItemEnabled(const std::string &item, bool enabled);
+ void setShownBtnEnabled(bool enabled);
+ void setMenuItemVisible(const std::string &item, bool visible);
+ void setMenuItemLabel(const std::string &item, const std::string &label);
+
+ U32 getItemCount();
+ void setSelectedItem(S32 itemno);
+ void setSelectedItem(const std::string &item);
+
+ void setAction(LLUICtrl::commit_callback_t cb);
+
+protected:
+ void onFlyoutButton(LLUICtrl *, const LLSD &);
+ void onFlyoutItemSelected(LLUICtrl *, const LLSD &);
+ bool onFlyoutItemCheck(LLUICtrl *, const LLSD &);
+ void onFlyoutAction(LLUICtrl *, const LLSD &);
+
+ void setSelectedItem(LLMenuItemGL *pitem);
+
+private:
+ LLPanel * mParent;
+ LLToggleableMenu * mFlyoutMenu;
+ std::string mActionButton;
+ std::string mFlyoutButton;
+
+ std::string mSelectedName;
+ bool mApplyImmediately;
+
+ LLUICtrl::commit_signal_t mActionSignal;
+};
+#endif // LL_LLFLYOUTCOMBOBTN_H
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index dea54cbe57..51b98339c4 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -45,12 +45,14 @@ public:
virtual LLFolderType::EType getPreferredType() const = 0;
virtual void showProperties(void) = 0;
virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
+ virtual BOOL isAgentInventory() const { return FALSE; }
virtual BOOL isUpToDate() const = 0;
virtual bool hasChildren() const = 0;
virtual LLInventoryType::EType getInventoryType() const = 0;
virtual void performAction(LLInventoryModel* model, std::string action) = 0;
- virtual LLWearableType::EType getWearableType() const = 0;
- virtual EInventorySortGroup getSortGroup() const = 0;
+ virtual LLWearableType::EType getWearableType() const = 0;
+ virtual LLSettingsType::type_e getSettingsType() const = 0;
+ virtual EInventorySortGroup getSortGroup() const = 0;
virtual LLInventoryObject* getInventoryObject() const = 0;
virtual void requestSort();
virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 62cbea6401..0be748ace9 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -504,7 +504,7 @@ void LLFriendCardsManager::syncFriendsFolder()
gAgentID.asString(),
LLAssetType::AT_CALLINGCARD,
LLInventoryType::IT_CALLINGCARD,
- NOT_WEARABLE,
+ NO_INV_SUBTYPE,
PERM_MOVE | PERM_TRANSFER,
NULL);
}
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 3ab8fed2c6..127055459d 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -129,23 +129,14 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
- if (get_is_item_worn(item->getUUID()))
- {
- acceptable = false;
- }
- break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
{
- BOOL copyable = false;
- if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true;
-
- if (!copyable && get_is_item_worn(item->getUUID()))
+ if (get_is_item_worn(item->getUUID()))
{
- // worn no-copy items can't be transfered,
- // but it is valid to transfer a copy of a worn item
acceptable = false;
}
+ break;
}
break;
default:
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index fea01786f3..698c15bd2d 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -44,6 +44,7 @@
#include "llviewercamera.h"
#include "llvoavatarself.h"
+#include "llsky.h"
#include "llagent.h"
#include "lltoolmgr.h"
#include "llselectmgr.h"
@@ -771,6 +772,16 @@ void draw_line_cube(F32 width, const LLVector3& center)
gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
}
+void draw_cross_lines(const LLVector3& center, F32 dx, F32 dy, F32 dz)
+{
+ gGL.vertex3f(center.mV[VX] - dx, center.mV[VY], center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX] + dx, center.mV[VY], center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY] - dy, center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY] + dy, center.mV[VZ]);
+ gGL.vertex3f(center.mV[VX], center.mV[VY], center.mV[VZ] - dz);
+ gGL.vertex3f(center.mV[VX], center.mV[VY], center.mV[VZ] + dz);
+}
+
void LLViewerObjectList::renderObjectBeacons()
{
if (mDebugBeacons.empty())
@@ -808,13 +819,7 @@ void LLViewerObjectList::renderObjectBeacons()
gGL.begin(LLRender::LINES);
gGL.color4fv(color.mV);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
- gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
-
+ draw_cross_lines(thisline, 2.0f, 2.0f, 50.f);
draw_line_cube(0.10f, thisline);
gGL.end();
@@ -843,13 +848,7 @@ void LLViewerObjectList::renderObjectBeacons()
const LLVector3 &thisline = debug_beacon.mPositionAgent;
gGL.begin(LLRender::LINES);
gGL.color4fv(debug_beacon.mColor.mV);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
- gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
- gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
-
+ draw_cross_lines(thisline, 0.5f, 0.5f, 0.5f);
draw_line_cube(0.10f, thisline);
gGL.end();
@@ -880,6 +879,34 @@ void LLViewerObjectList::renderObjectBeacons()
}
}
+void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color)
+{
+ LLGLSUIDefault gls_ui;
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVector3 pos_end;
+ for (S32 i = 0; i < 3; ++i)
+ {
+ pos_end.mV[i] = pos_agent.mV[i] + (50 * direction.mV[i]);
+ }
+ glLineWidth(LLPipeline::DebugBeaconLineWidth);
+ gGL.begin(LLRender::LINES);
+ color.mV[3] *= 0.5f;
+ gGL.color4fv(color.mV);
+ draw_cross_lines(pos_agent, 0.5f, 0.5f, 0.5f);
+ draw_cross_lines(pos_end, 2.f, 2.f, 2.f);
+ gGL.vertex3fv(pos_agent.mV);
+ gGL.vertex3fv(pos_end.mV);
+ gGL.end();
+
+ gGL.flush();
+ glLineWidth(1.f);
+
+}
//-----------------------------------------------------------------------------
// gpu_benchmark() helper classes
@@ -1005,7 +1032,7 @@ F32 gpu_benchmark()
//number of samples to take
const S32 samples = 64;
-
+
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
@@ -1133,7 +1160,7 @@ F32 gpu_benchmark()
F32 gbps = results[results.size()/2];
LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
-
+
#if LL_DARWIN
if (gbps > 512.f)
{
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 599790d2bb..12d82d101f 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -39,6 +39,7 @@
#include "llfloaterimcontainer.h"
#include "llimview.h" // for gIMMgr
#include "llnotificationsutil.h"
+#include "llstartup.h"
#include "llstatusbar.h" // can_afford_transaction()
#include "groupchatlistener.h"
@@ -55,6 +56,11 @@ public:
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo"))
{
LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
@@ -400,10 +406,10 @@ void LLGroupActions::createGroup()
{
LLSD params;
params["group_id"] = LLUUID::null;
- params["open_tab_name"] = "panel_group_info_sidetray";
+ params["open_tab_name"] = "panel_group_creation_sidetray";
params["action"] = "create";
- LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params);
+ LLFloaterSidePanelContainer::showPanel("people", "panel_group_creation_sidetray", params);
}
//static
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 088d052533..32f88b49ac 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -44,9 +44,8 @@
#include "roles_constants.h"
#include "lltransactiontypes.h"
#include "llstatusbar.h"
-#include "lleconomy.h"
#include "llviewerwindow.h"
-#include "llpanelgroup.h"
+#include "llpanelgroupcreate.h"
#include "llgroupactions.h"
#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
@@ -945,10 +944,14 @@ static void formatDateString(std::string &date_string)
}
}
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members");
+
// static
void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
{
- LL_DEBUGS() << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY);
+
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL;
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
if (gAgent.getID() != agent_id)
@@ -1051,10 +1054,14 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
}
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties");
+
//static
void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
{
- LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY);
+
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL;
if (!msg)
{
LL_ERRS() << "Can't access the messaging system" << LL_ENDL;
@@ -1120,13 +1127,25 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)
group_datap->mGroupPropertiesDataComplete = true;
group_datap->mChanged = TRUE;
+ properties_request_map_t::iterator request = LLGroupMgr::getInstance()->mPropRequests.find(group_id);
+ if (request != LLGroupMgr::getInstance()->mPropRequests.end())
+ {
+ LLGroupMgr::getInstance()->mPropRequests.erase(request);
+ }
+ else
+ {
+ LL_DEBUGS("GrpMgr") << "GroupPropertyResponse received with no pending request. Response was slow." << LL_ENDL;
+ }
LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES);
}
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data");
// static
void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
{
- LL_DEBUGS() << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY);
+
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL;
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
if (gAgent.getID() != agent_id)
@@ -1187,7 +1206,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
- LL_DEBUGS() << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL;
LLGroupRoleData* rd = new LLGroupRoleData(role_id,name,title,desc,powers,member_count);
group_datap->mRoles[role_id] = rd;
}
@@ -1208,10 +1227,13 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)
LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA);
}
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members");
// static
void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
{
- LL_DEBUGS() << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY);
+
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL;
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
if (gAgent.getID() != agent_id)
@@ -1272,7 +1294,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
if (rd && md)
{
- LL_DEBUGS() << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL;
rd->addMember(member_id);
md->addRole(role_id,rd);
}
@@ -1324,7 +1346,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)
// static
void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
{
- LL_DEBUGS() << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL;
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
if (gAgent.getID() != agent_id)
@@ -1357,7 +1379,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
if (!title.mTitle.empty())
{
- LL_DEBUGS() << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL;
group_datap->mTitles.push_back(title);
}
}
@@ -1369,7 +1391,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)
// static
void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data)
{
- LL_DEBUGS() << "processEjectGroupMemberReply" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "processEjectGroupMemberReply" << LL_ENDL;
LLUUID group_id;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
BOOL success;
@@ -1385,7 +1407,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data
// static
void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
{
- LL_DEBUGS() << "processJoinGroupReply" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "processJoinGroupReply" << LL_ENDL;
LLUUID group_id;
BOOL success;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
@@ -1405,7 +1427,7 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data)
// static
void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data)
{
- LL_DEBUGS() << "processLeaveGroupReply" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "processLeaveGroupReply" << LL_ENDL;
LLUUID group_id;
BOOL success;
msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id);
@@ -1452,7 +1474,7 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
gAgent.mGroups.push_back(gd);
- LLPanelGroup::refreshCreatedGroup(group_id);
+ LLPanelGroupCreate::refreshCreatedGroup(group_id);
//FIXME
//LLFloaterGroupInfo::closeCreateGroup();
//LLFloaterGroupInfo::showFromUUID(group_id,"roles_tab");
@@ -1489,6 +1511,28 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
return group_datap;
}
+bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id)
+{
+ properties_request_map_t::iterator existing_req = LLGroupMgr::getInstance()->mPropRequests.find(id);
+ if (existing_req != LLGroupMgr::getInstance()->mPropRequests.end())
+ {
+ if (gFrameTime - existing_req->second < MIN_GROUP_PROPERTY_REQUEST_FREQ)
+ {
+ return true;
+ }
+ else
+ {
+ LLGroupMgr::getInstance()->mPropRequests.erase(existing_req);
+ }
+ }
+ return false;
+}
+
+void LLGroupMgr::addPendingPropertyRequest(const LLUUID& id)
+{
+ LLGroupMgr::getInstance()->mPropRequests[id] = gFrameTime;
+}
+
void LLGroupMgr::notifyObservers(LLGroupChange gc)
{
for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi)
@@ -1567,10 +1611,17 @@ void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap)
void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL;
// This will happen when we get the reply
//LLGroupMgrGroupData* group_datap = createGroupData(group_id);
+ if (LLGroupMgr::getInstance()->hasPendingPropertyRequest(group_id))
+ {
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest suppressed repeat for " << group_id << LL_ENDL;
+ return;
+ }
+ LLGroupMgr::getInstance()->addPendingPropertyRequest(group_id);
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("GroupProfileRequest");
msg->nextBlock("AgentData");
@@ -1583,7 +1634,7 @@ void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id)
void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
if (group_datap->mMemberRequestID.isNull())
{
@@ -1605,7 +1656,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
if (group_datap->mRoleDataRequestID.isNull())
{
@@ -1626,7 +1677,7 @@ void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
if (group_datap->mRoleMembersRequestID.isNull())
@@ -1636,7 +1687,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
|| !group_datap->isRoleDataComplete())
{
// *TODO: KLW FIXME: Should we start a member or role data request?
- LL_INFOS() << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
+ LL_INFOS("GrpMgr") << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N")
<< " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N")
<< " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL;
group_datap->mPendingRoleMemberRequest = TRUE;
@@ -1660,7 +1711,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id)
void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
group_datap->mTitles.clear();
@@ -1679,7 +1730,7 @@ void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id)
void LLGroupMgr::sendGroupTitleUpdate(const LLUUID& group_id, const LLUUID& title_role_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("GroupTitleUpdate");
@@ -1738,7 +1789,7 @@ void LLGroupMgr::sendCreateGroupRequest(const std::string& name,
void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
LLMessageSystem* msg = gMessageSystem;
@@ -1767,7 +1818,7 @@ void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id)
void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL;
LLGroupMgrGroupData* group_datap = createGroupData(group_id);
if (group_datap->mRoleMemberChanges.empty()) return;
@@ -2314,7 +2365,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL;
LLGroupMgrGroupData* group_datap = getGroupData(group_id);
if (group_datap && group_datap->pendingRoleChanges())
@@ -2329,7 +2380,7 @@ void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id)
{
- LL_DEBUGS() << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL;
LLGroupMgrGroupData* group_datap = getGroupData(group_id);
if (group_datap) group_datap->cancelRoleChanges();
@@ -2363,7 +2414,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename)
std::string action_set_name;
if (action_set->getAttributeString("name", action_set_name))
{
- LL_DEBUGS() << "Loading action set " << action_set_name << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "Loading action set " << action_set_name << LL_ENDL;
role_action_data->mName = action_set_name;
}
else
@@ -2404,7 +2455,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename)
std::string action_name;
if (action->getAttributeString("name", action_name))
{
- LL_DEBUGS() << "Loading action " << action_name << LL_ENDL;
+ LL_DEBUGS("GrpMgr") << "Loading action " << action_name << LL_ENDL;
role_action->mName = action_name;
}
else
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index cf9735e38a..0d25e8fb22 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -448,6 +448,8 @@ private:
void notifyObserver(const LLUUID& group_id, LLGroupChange gc);
void addGroup(LLGroupMgrGroupData* group_datap);
LLGroupMgrGroupData* createGroupData(const LLUUID &id);
+ bool hasPendingPropertyRequest(const LLUUID& id);
+ void addPendingPropertyRequest(const LLUUID& id);
typedef std::multimap<LLUUID,LLGroupMgrObserver*> observer_multimap_t;
observer_multimap_t mObservers;
@@ -455,6 +457,10 @@ private:
typedef std::map<LLUUID, LLGroupMgrGroupData*> group_map_t;
group_map_t mGroups;
+ const U64MicrosecondsImplicit MIN_GROUP_PROPERTY_REQUEST_FREQ = 100000;//100ms between requests should be enough to avoid spamming.
+ typedef std::map<LLUUID, U64MicrosecondsImplicit> properties_request_map_t;
+ properties_request_map_t mPropRequests;
+
typedef std::set<LLParticularGroupObserver*> observer_set_t;
typedef std::map<LLUUID,observer_set_t> observer_map_t;
observer_map_t mParticularObservers;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 81d862a827..4ed802138d 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -415,7 +415,8 @@ void LLHUDNameTag::clearString()
void LLHUDNameTag::addLine(const std::string &text_utf8,
const LLColor4& color,
const LLFontGL::StyleFlags style,
- const LLFontGL* font)
+ const LLFontGL* font,
+ const bool use_ellipses)
{
LLWString wline = utf8str_to_wstring(text_utf8);
if (!wline.empty())
@@ -432,18 +433,52 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
tokenizer tokens(wline, sep);
tokenizer::iterator iter = tokens.begin();
- while (iter != tokens.end())
- {
- U32 line_length = 0;
- do
- {
- F32 max_pixels = HUD_TEXT_MAX_WIDTH;
- S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
- LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
- mTextSegments.push_back(segment);
- line_length += segment_length;
- }
- while (line_length != iter->size());
+ const F32 max_pixels = HUD_TEXT_MAX_WIDTH;
+ while (iter != tokens.end())
+ {
+ U32 line_length = 0;
+ if (use_ellipses)
+ {
+ // "QualityAssuranceAssuresQuality1" will end up like "QualityAssuranceAssuresQual..."
+ // "QualityAssuranceAssuresQuality QualityAssuranceAssuresQuality" will end up like "QualityAssuranceAssuresQual..."
+ // "QualityAssurance AssuresQuality1" will end up as "QualityAssurance AssuresQua..." because we are enforcing single line
+ do
+ {
+ S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::ANYWHERE);
+ if (segment_length + line_length < wline.length()) // since we only draw one string, line_length should be 0
+ {
+ // token does does not fit into signle line, need to draw "...".
+ // Use four dots for ellipsis width to generate padding
+ const LLWString dots_pad(utf8str_to_wstring(std::string("....")));
+ S32 elipses_width = font->getWidthF32(dots_pad.c_str());
+ // truncated string length
+ segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE);
+ const LLWString dots(utf8str_to_wstring(std::string("...")));
+ LLHUDTextSegment segment(iter->substr(line_length, segment_length) + dots, style, color, font);
+ mTextSegments.push_back(segment);
+ break; // consider it to be complete
+ }
+ else
+ {
+ // token fits fully into string
+ LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
+ mTextSegments.push_back(segment);
+ line_length += segment_length;
+ }
+ } while (line_length != iter->size());
+ }
+ else
+ {
+ // "QualityAssuranceAssuresQuality 1" will be split into two lines "QualityAssuranceAssuresQualit" and "y 1"
+ // "QualityAssurance AssuresQuality 1" will be split into two lines "QualityAssurance" and "AssuresQuality"
+ do
+ {
+ S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
+ LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font);
+ mTextSegments.push_back(segment);
+ line_length += segment_length;
+ } while (line_length != iter->size());
+ }
++iter;
}
}
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 38a4f18415..20272a8232 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -92,7 +92,7 @@ public:
void clearString();
// Add text a line at a time, allowing custom formatting
- void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL);
+ void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false);
// For bubble chat, set the part above the chat text
void setLabel(const std::string& label_utf8);
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2f7a98c86c..ce128519ea 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -102,7 +102,7 @@ protected:
static void sortObjects();
LLHUDObject(const U8 type);
- ~LLHUDObject();
+ virtual ~LLHUDObject();
virtual void render() = 0;
virtual void renderForTimer() {};
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index ef3b234f50..72d28a3d44 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -565,7 +565,10 @@ S32 LLHUDText::getMaxLines()
void LLHUDText::markDead()
{
- sTextObjects.erase(LLPointer<LLHUDText>(this));
+ // make sure we have at least one pointer
+ // till the end of the function
+ LLPointer<LLHUDText> ptr(this);
+ sTextObjects.erase(ptr);
LLHUDObject::markDead();
}
@@ -589,8 +592,6 @@ void LLHUDText::renderAllHUD()
LLVertexBuffer::unbind();
- LLVertexBuffer::unbind();
-
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index e3705e82b9..1e43e4ea3a 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -29,6 +29,7 @@
#include "llimprocessing.h"
#include "llagent.h"
+#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llfirstuse.h"
#include "llfloaterreg.h"
@@ -61,6 +62,8 @@
#pragma warning (disable:4702)
#endif
+extern void on_new_message(const LLSD& msg);
+
// Strip out "Resident" for display, but only if the message came from a user
// (rather than a script)
static std::string clean_name_from_im(const std::string& name, EInstantMessage type)
@@ -447,7 +450,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|| (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id));
BOOL is_owned_by_me = FALSE;
BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
- BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
+ BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly");
BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
LLMuteList::getInstance()->isLinden(name);
@@ -854,41 +857,41 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
else // IM_TASK_INVENTORY_OFFERED
{
- if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
+ if (sizeof(S8) == binary_bucket_size)
{
- // cap received offline message
- std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
- tokenizer tokens(str_bucket, sep);
- tokenizer::iterator iter = tokens.begin();
-
- info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
- // Note There is more elements in 'tokens' ...
-
- info->mObjectID = LLUUID::null;
- info->mFromObject = TRUE;
+ info->mType = (LLAssetType::EType) binary_bucket[0];
}
else
{
- if (sizeof(S8) != binary_bucket_size)
- {
- LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
- delete info;
- break;
- }
- info->mType = (LLAssetType::EType) binary_bucket[0];
- info->mObjectID = LLUUID::null;
- info->mFromObject = TRUE;
+ /*RIDER*/ // The previous version of the protocol returned the wrong binary bucket... we
+ // still might be able to figure out the type... even though the offer is not retrievable.
+
+ // Should be safe to remove once DRTSIM-451 fully deploys
+ std::string str_bucket(reinterpret_cast<char *>(binary_bucket));
+ std::string str_type(str_bucket.substr(0, str_bucket.find('|')));
+
+ std::stringstream type_convert(str_type);
+
+ S32 type;
+ type_convert >> type;
+
+ // We could try AT_UNKNOWN which would be more accurate, but that causes an auto decline
+ info->mType = static_cast<LLAssetType::EType>(type);
+ // Don't break in the case of a bad binary bucket. Go ahead and show the
+ // accept/decline popup even though it will not do anything.
+ LL_WARNS("Messaging") << "Malformed inventory offer from object, type might be " << info->mType << LL_ENDL;
}
+ info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
}
info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
- info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+ info->mTransactionID = session_id.notNull() ? session_id : aux_id;
+
info->mFromName = name;
info->mDesc = message;
info->mHost = sender;
@@ -1027,6 +1030,14 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
+ if (message != "")
+ {
+ LLSD msg_notify;
+ msg_notify["session_id"] = LLUUID();
+ msg_notify["from_id"] = chat.mFromID;
+ msg_notify["source_type"] = chat.mSourceType;
+ on_new_message(msg_notify);
+ }
}
@@ -1153,7 +1164,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
{
return;
}
- else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
+ else if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
{
return;
}
@@ -1393,10 +1404,8 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
payload["sender"] = sender.getIPandPort();
bool add_notification = true;
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ for (auto& panel : LLToastNotifyPanel::instance_snapshot())
{
- LLToastNotifyPanel& panel = *ti;
const std::string& notification_name = panel.getNotificationName();
if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
{
@@ -1474,6 +1483,7 @@ void LLIMProcessing::requestOfflineMessages()
static BOOL requested = FALSE;
if (!requested
&& gMessageSystem
+ && !gDisconnected
&& LLMuteList::getInstance()->isLoaded()
&& isAgentAvatarValid()
&& gAgent.getRegion()
@@ -1557,11 +1567,15 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
return;
}
+ if (!gAgent.getRegion())
+ {
+ LL_WARNS("Messaging") << "Region null while attempting to load messages." << LL_ENDL;
+ return;
+ }
+
LL_INFOS("Messaging") << "Processing offline messages." << LL_ENDL;
- std::vector<U8> data;
- S32 binary_bucket_size = 0;
- LLHost sender = gAgent.getRegion()->getHost();
+ LLHost sender = gAgent.getRegionHost();
LLSD::array_iterator i = messages.beginArray();
LLSD::array_iterator iEnd = messages.endArray();
@@ -1569,12 +1583,30 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
{
const LLSD &message_data(*i);
- LLVector3 position(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
- data = message_data["binary_bucket"].asBinary();
- binary_bucket_size = data.size(); // message_data["count"] always 0
- U32 parent_estate_id = message_data.has("parent_estate_id") ? message_data["parent_estate_id"].asInteger() : 1; // 1 - IMMainland
+ /* RIDER: Many fields in this message are using a '_' rather than the standard '-'. This
+ * should be changed but would require tight coordination with the simulator.
+ */
+ LLVector3 position;
+ if (message_data.has("position"))
+ {
+ position.setValue(message_data["position"]);
+ }
+ else
+ {
+ position.set(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
+ }
+
+ std::vector<U8> bin_bucket;
+ if (message_data.has("binary_bucket"))
+ {
+ bin_bucket = message_data["binary_bucket"].asBinary();
+ }
+ else
+ {
+ bin_bucket.push_back(0);
+ }
- // Todo: once dirtsim-369 releases, remove one of the int/str options
+ // Todo: once drtsim-451 releases, remove the string option
BOOL from_group;
if (message_data["from_group"].isInteger())
{
@@ -1585,22 +1617,25 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
from_group = message_data["from_group"].asString() == "Y";
}
- LLIMProcessing::processNewMessage(message_data["from_agent_id"].asUUID(),
+
+ LLIMProcessing::processNewMessage(
+ message_data["from_agent_id"].asUUID(),
from_group,
message_data["to_agent_id"].asUUID(),
- IM_OFFLINE,
- (EInstantMessage)message_data["dialog"].asInteger(),
- LLUUID::null, // session id, since there is none we can only use frienship/group invite caps
- message_data["timestamp"].asInteger(),
+ message_data.has("offline") ? static_cast<U8>(message_data["offline"].asInteger()) : IM_OFFLINE,
+ static_cast<EInstantMessage>(message_data["dialog"].asInteger()),
+ message_data["transaction-id"].asUUID(),
+ static_cast<U32>(message_data["timestamp"].asInteger()),
message_data["from_agent_name"].asString(),
message_data["message"].asString(),
- parent_estate_id,
+ static_cast<U32>((message_data.has("parent_estate_id")) ? message_data["parent_estate_id"].asInteger() : 1), // 1 - IMMainland
message_data["region_id"].asUUID(),
position,
- &data[0],
- binary_bucket_size,
+ bin_bucket.data(),
+ bin_bucket.size(),
sender,
- message_data["asset_id"].asUUID()); // not necessarily an asset
+ message_data["asset_id"].asUUID());
+
}
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e331a51bda..1059324a16 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -515,6 +515,7 @@ LLIMModel::LLIMModel()
{
addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
addNewMsgCallback(boost::bind(&on_new_message, _1));
+ LLCallDialogManager::instance();
}
LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
@@ -843,7 +844,7 @@ void LLIMModel::LLIMSession::loadHistory()
std::list<LLSD> chat_history;
//involves parsing of a chat history
- LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+ LLLogChat::loadChatHistory(mHistoryFileName, chat_history, LLSD(), isGroupChat());
addMessagesFromHistory(chat_history);
}
}
@@ -907,6 +908,11 @@ bool LLIMModel::LLIMSession::isP2P()
return IM_NOTHING_SPECIAL == mType;
}
+bool LLIMModel::LLIMSession::isGroupChat()
+{
+ return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID));
+}
+
bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
{
return !mOtherParticipantIsAvatar;
@@ -963,6 +969,13 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
// Incoming P2P sessions include a name that we can use to build a history file name
mHistoryFileName = LLCacheName::buildUsername(mName);
}
+
+ // user's account name can change, but filenames and session names are account name based
+ LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName());
+ }
+ else if (isGroupChat())
+ {
+ mHistoryFileName = mName + GROUP_CHAT_SUFFIX;
}
}
@@ -2244,6 +2257,19 @@ BOOL LLOutgoingCallDialog::postBuild()
// Class LLIncomingCallDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const std::array<std::string, 4> voice_call_types =
+{
+ "VoiceInviteP2P",
+ "VoiceInviteGroup",
+ "VoiceInviteAdHoc",
+ "InviteAdHoc"
+};
+
+bool is_voice_call_type(const std::string &value)
+{
+ return std::find(voice_call_types.begin(), voice_call_types.end(), value) != voice_call_types.end();
+}
+
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
LLCallDialog(payload),
mAvatarNameCacheConnection()
@@ -2273,9 +2299,28 @@ BOOL LLIncomingCallDialog::postBuild()
{
LLCallDialog::postBuild();
+ if (!mPayload.isMap() || mPayload.size() == 0)
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: invalid argument" << LL_ENDL;
+ return TRUE;
+ }
+
LLUUID session_id = mPayload["session_id"].asUUID();
LLSD caller_id = mPayload["caller_id"];
std::string caller_name = mPayload["caller_name"].asString();
+
+ if (session_id.isNull() && caller_id.asUUID().isNull())
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: invalid ids" << LL_ENDL;
+ return TRUE;
+ }
+
+ std::string notify_box_type = mPayload["notify_box_type"].asString();
+ if (!is_voice_call_type(notify_box_type))
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: notify_box_type was not provided" << LL_ENDL;
+ return TRUE;
+ }
// init notification's lifetime
std::istringstream ss( getString("lifetime") );
@@ -2292,15 +2337,14 @@ BOOL LLIncomingCallDialog::postBuild()
if (gAgent.getGroupData(session_id, data))
{
args["[GROUP]"] = data.mName;
- call_type = getString(mPayload["notify_box_type"], args);
+ call_type = getString(notify_box_type, args);
}
}
else
{
- call_type = getString(mPayload["notify_box_type"]);
+ 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")
@@ -2330,7 +2374,6 @@ BOOL LLIncomingCallDialog::postBuild()
childSetAction("Start IM", onStartIM, this);
setDefaultBtn("Accept");
- std::string notify_box_type = mPayload["notify_box_type"].asString();
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
// starting notification's timer for P2P and AVALINE invitations
@@ -2481,10 +2524,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
correct_session_name.append(ADHOC_NAME_SUFFIX);
}
}
- LL_INFOS() << "Corrected session name is " << correct_session_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Corrected session name is " << correct_session_name << LL_ENDL;
break;
default:
- LL_WARNS() << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
+ LL_WARNS("IMVIEW") << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
break;
}
}
@@ -2674,7 +2717,7 @@ void LLIMMgr::addMessage(
}
bool skip_message = false;
bool from_linden = LLMuteList::getInstance()->isLinden(from);
- if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
+ if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
{
// Evaluate if we need to skip this message when that setting is true (default is false)
skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends...
@@ -2684,6 +2727,14 @@ void LLIMMgr::addMessage(
bool new_session = !hasSession(new_session_id);
if (new_session)
{
+ // Group chat session was initiated by muted resident, do not start this session viewerside
+ // do not send leave msg either, so we are able to get group messages from other participants
+ if ((IM_SESSION_INVITE == dialog) && gAgent.isInGroup(new_session_id) &&
+ LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
+ {
+ return;
+ }
+
LLAvatarName av_name;
if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
{
@@ -2727,13 +2778,13 @@ void LLIMMgr::addMessage(
LL_WARNS() << "Leaving IM session from initiating muted resident " << from << LL_ENDL;
if (!gIMMgr->leaveSession(new_session_id))
{
- LL_INFOS() << "Session " << new_session_id << " does not exist." << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Session " << new_session_id << " does not exist." << LL_ENDL;
}
return;
}
//Play sound for new conversations
- if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
+ if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
{
make_ui_sound("UISndNewIncomingIMSession");
}
@@ -2938,7 +2989,7 @@ LLUUID LLIMMgr::addSession(
//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
if (!new_session) return session_id;
- LL_INFOS() << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
+ LL_INFOS("IMVIEW") << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
//*TODO After February 2010 remove this commented out line if no one will be missing that warning
@@ -2975,7 +3026,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
LLIMModel::getInstance()->clearSession(session_id);
- LL_INFOS() << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
+ LL_INFOS("IMVIEW") << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
notifyObserverSessionRemoved(session_id);
}
@@ -3041,13 +3092,13 @@ void LLIMMgr::inviteToSession(
if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagVoiceChat)
&& voice_invite && "VoiceInviteQuestionDefault" == question_type)
{
- LL_INFOS() << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
LLIncomingCallDialog::processCallResponse(1, payload);
return;
}
else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite)
{
- LL_INFOS() << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
return;
}
}
@@ -3063,7 +3114,7 @@ void LLIMMgr::inviteToSession(
if (voice_invite)
{
bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
- bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
+ bool isRejectNonFriendCall = (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
if (isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb())
{
if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall)
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 2a9e4679a8..79c831ebb6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -91,6 +91,7 @@ public:
bool isOutgoingAdHoc() const;
bool isAdHoc();
bool isP2P();
+ bool isGroupChat();
bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 6d2d533c9d..8b61e6c61a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -81,6 +81,10 @@
#include "llwearableitemslist.h"
#include "lllandmarkactions.h"
#include "llpanellandmarks.h"
+#include "llviewerparcelmgr.h"
+#include "llparcel.h"
+
+#include "llenvironment.h"
#include <boost/shared_ptr.hpp>
@@ -1408,6 +1412,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
//LL_WARNS() << LLAssetType::lookup(asset_type) << " asset type is unhandled for uuid " << uuid << LL_ENDL;
break;
+ case LLAssetType::AT_SETTINGS:
+ if (inv_type != LLInventoryType::IT_SETTINGS)
+ {
+ LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
+ }
+ new_listener = new LLSettingsBridge(inventory, root, uuid, LLSettingsType::fromInventoryFlags(flags));
+ break;
+
default:
LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
@@ -1797,7 +1809,7 @@ void LLItemBridge::restoreToWorld()
msg->nextBlockFast(_PREHASH_InventoryData);
itemp->packMessage(msg);
- msg->sendReliable(gAgent.getRegion()->getHost());
+ msg->sendReliable(gAgent.getRegionHost());
//remove local inventory copy, sim will deal with permissions and removing the item
//from the actual inventory if its a no-copy etc
@@ -1823,28 +1835,11 @@ void LLItemBridge::restoreToWorld()
void LLItemBridge::gotoItem()
{
- LLInventoryObject *obj = getInventoryObject();
- if (obj && obj->getIsLinkType())
- {
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
- if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id))
- {
- LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- if (sidepanel_inventory && sidepanel_inventory->getInboxPanel())
- {
- sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
- }
- }
- else
- {
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
- if (active_panel)
- {
- active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
- }
- }
-
- }
+ LLInventoryObject *obj = getInventoryObject();
+ if (obj && obj->getIsLinkType())
+ {
+ show_item_original(obj->getUUID());
+ }
}
LLUIImagePtr LLItemBridge::getIcon() const
@@ -2270,7 +2265,7 @@ public:
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable() const
{
- if (!get_is_category_removable(getInventoryModel(), mUUID) || isMarketplaceListingsFolder())
+ if (!get_is_category_removable(getInventoryModel(), mUUID))
{
return FALSE;
}
@@ -2287,6 +2282,11 @@ BOOL LLFolderBridge::isItemRemovable() const
}
}
+ if (isMarketplaceListingsFolder() && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID)))
+ {
+ return FALSE;
+ }
+
return TRUE;
}
@@ -3988,6 +3988,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Folder"));
disabled_items.push_back(std::string("New Script"));
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 Clothes"));
disabled_items.push_back(std::string("New Body Parts"));
@@ -4081,7 +4082,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
items.push_back(std::string("New Gesture"));
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"));
+
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ disabled_items.push_back("New Settings");
+ }
+
}
}
getClipboardEntries(false, items, disabled_items, flags);
@@ -4347,6 +4355,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
+ case DAD_SETTINGS:
accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
break;
case DAD_LINK:
@@ -5226,6 +5235,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
}
+ else if ((inv_item->getActualType() == LLAssetType::AT_SETTINGS) && !LLEnvironment::instance().isInventoryEnabled())
+ {
+ tooltip_msg = LLTrans::getString("NoEnvironmentSettings");
+ accept = FALSE;
+ }
else
{
// Don't allow placing an original item from a notecard to Current Outfit or an outfit folder
@@ -5942,6 +5956,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
+ case DAD_SETTINGS:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();
@@ -6353,6 +6368,14 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
{
LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, false); // Don't replace if adding.
}
+ else if ("touch" == action)
+ {
+ handle_attachment_touch(mUUID);
+ }
+ else if ("edit" == action)
+ {
+ handle_attachment_edit(mUUID);
+ }
else if (isRemoveAction(action))
{
LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
@@ -6503,6 +6526,19 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if( get_is_item_worn( mUUID ) )
{
items.push_back(std::string("Wearable And Object Separator"));
+
+ items.push_back(std::string("Attachment Touch"));
+ if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !enable_attachment_touch(mUUID) )
+ {
+ disabled_items.push_back(std::string("Attachment Touch"));
+ }
+
+ items.push_back(std::string("Wearable Edit"));
+ if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !get_is_item_editable(mUUID) )
+ {
+ disabled_items.push_back(std::string("Wearable Edit"));
+ }
+
items.push_back(std::string("Detach From Yourself"));
}
else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing() && !isCOFFolder())
@@ -6963,6 +6999,153 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
+// +=================================================+
+// | LLSettingsBridge |
+// +=================================================+
+
+LLSettingsBridge::LLSettingsBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid,
+ LLSettingsType::type_e settings_type):
+ LLItemBridge(inventory, root, uuid),
+ mSettingsType(settings_type)
+{
+}
+
+LLUIImagePtr LLSettingsBridge::getIcon() const
+{
+ return LLInventoryIcon::getIcon(LLAssetType::AT_SETTINGS, LLInventoryType::IT_SETTINGS, mSettingsType, FALSE);
+}
+
+void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action)
+{
+ if ("apply_settings_local" == action)
+ {
+ // Single item only
+ LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
+ if (!item)
+ return;
+ LLUUID asset_id = item->getAssetUUID();
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ }
+ else if ("apply_settings_parcel" == action)
+ {
+ // Single item only
+ LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
+ if (!item)
+ return;
+ LLUUID asset_id = item->getAssetUUID();
+ std::string name = item->getName();
+
+ U32 flags(0);
+
+ if (!item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOMOD;
+ if (!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOTRANS;
+
+ LLParcel *parcel = LLViewerParcelMgr::instance().getAgentOrSelectedParcel();
+ if (!parcel)
+ {
+ LL_WARNS("INVENTORY") << "could not identify parcel." << LL_ENDL;
+ return;
+ }
+ S32 parcel_id = parcel->getLocalID();
+
+ LL_DEBUGS("ENVIRONMENT") << "Applying asset ID " << asset_id << " to parcel " << parcel_id << LL_ENDL;
+ LLEnvironment::instance().updateParcel(parcel_id, asset_id, name, LLEnvironment::NO_TRACK, -1, -1, flags);
+ LLEnvironment::instance().setSharedEnvironment();
+ }
+ else
+ LLItemBridge::performAction(model, action);
+}
+
+void LLSettingsBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ if (item->getPermissions().getOwner() != gAgent.getID())
+ LLNotificationsUtil::add("NoEditFromLibrary");
+ else
+ LLInvFVBridgeAction::doAction(item->getType(), mUUID, getInventoryModel());
+ }
+}
+
+void LLSettingsBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LL_DEBUGS() << "LLSettingsBridge::buildContextMenu()" << LL_ENDL;
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+
+ 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 if (isItemInTrash())
+ {
+ addTrashContextMenuOptions(items, disabled_items);
+ }
+ else
+ {
+ items.push_back(std::string("Share"));
+ if (!canShare())
+ {
+ disabled_items.push_back(std::string("Share"));
+ }
+
+ addOpenRightClickMenuOption(items);
+ items.push_back(std::string("Properties"));
+
+ getClipboardEntries(true, items, disabled_items, flags);
+
+ items.push_back("Settings Separator");
+ items.push_back("Settings Apply Local");
+
+ items.push_back("Settings Apply Parcel");
+ if (!canUpdateParcel())
+ disabled_items.push_back("Settings Apply Parcel");
+
+ items.push_back("Settings Apply Region");
+ if (!canUpdateRegion())
+ disabled_items.push_back("Settings Apply Region");
+ }
+ addLinkReplaceMenuOption(items, disabled_items);
+ hide_context_entries(menu, items, disabled_items);
+}
+
+BOOL LLSettingsBridge::renameItem(const std::string& new_name)
+{
+ /*TODO: change internal settings name? */
+ return LLItemBridge::renameItem(new_name);
+}
+
+BOOL LLSettingsBridge::isItemRenameable() const
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ return (item->getPermissions().allowModifyBy(gAgent.getID()));
+ }
+ return FALSE;
+}
+
+bool LLSettingsBridge::canUpdateParcel() const
+{
+ return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+}
+
+bool LLSettingsBridge::canUpdateRegion() const
+{
+ return LLEnvironment::instance().canAgentUpdateRegionEnvironment();
+}
+
// +=================================================+
// | LLLinkBridge |
@@ -7018,21 +7201,17 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti
}
void LLLinkFolderBridge::gotoItem()
{
- const LLUUID &cat_uuid = getFolderID();
- if (!cat_uuid.isNull())
- {
- LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
- if (base_folder)
- {
- if (LLInventoryModel* model = getInventoryModel())
- {
- model->fetchDescendentsOf(cat_uuid);
- }
- base_folder->setOpen(TRUE);
- mRoot->setSelection(base_folder,TRUE);
- mRoot->scrollToShowSelection();
- }
- }
+ LLItemBridge::gotoItem();
+
+ const LLUUID &cat_uuid = getFolderID();
+ if (!cat_uuid.isNull())
+ {
+ LLFolderViewItem *base_folder = LLInventoryPanel::getActiveInventoryPanel()->getItemByID(cat_uuid);
+ if (base_folder)
+ {
+ base_folder->setOpen(TRUE);
+ }
+ }
}
const LLUUID &LLLinkFolderBridge::getFolderID() const
{
@@ -7322,6 +7501,40 @@ void LLWearableBridgeAction::wearOnAvatar()
}
}
+class LLSettingsBridgeAction
+ : public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ virtual void doIt()
+ {
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLSettingsType::type_e type = item->getSettingsType();
+ switch (type)
+ {
+ case LLSettingsType::ST_SKY:
+ LLFloaterReg::showInstance("env_fixed_environmentent_sky", LLSDMap("inventory_id", item->getUUID()), TAKE_FOCUS_YES);
+ break;
+ case LLSettingsType::ST_WATER:
+ LLFloaterReg::showInstance("env_fixed_environmentent_water", LLSDMap("inventory_id", item->getUUID()), TAKE_FOCUS_YES);
+ break;
+ case LLSettingsType::ST_DAYCYCLE:
+ LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("inventory_id", item->getUUID())("edit_context", "inventory"), TAKE_FOCUS_YES);
+ break;
+ default:
+ break;
+ }
+ }
+ LLInvFVBridgeAction::doIt();
+ }
+ virtual ~LLSettingsBridgeAction(){}
+protected:
+ LLSettingsBridgeAction(const LLUUID& id, LLInventoryModel* model) : LLInvFVBridgeAction(id, model) {}
+};
+
+
LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
const LLUUID& uuid,
LLInventoryModel* model)
@@ -7360,6 +7573,9 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
case LLAssetType::AT_BODYPART:
action = new LLWearableBridgeAction(uuid,model);
break;
+ case LLAssetType::AT_SETTINGS:
+ action = new LLSettingsBridgeAction(uuid, model);
+ break;
default:
break;
}
@@ -7434,11 +7650,11 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ
disable_context_entries_if_present(menu, disabled_items);
}
-bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
+bool LLFolderViewGroupedItemBridge::canWearSelected(const uuid_vec_t& item_ids) const
{
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
- LLViewerInventoryItem* item = gInventory.getItem(*it);
+ const LLViewerInventoryItem* item = gInventory.getItem(*it);
if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
{
return false;
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 0823cf8b52..9af8664388 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -38,6 +38,7 @@
#include "lltooldraganddrop.h"
#include "lllandmarklist.h"
#include "llfolderviewitem.h"
+#include "llsettingsbase.h"
class LLInventoryFilter;
class LLInventoryPanel;
@@ -108,6 +109,7 @@ public:
virtual void closeItem() {}
virtual void showProperties();
virtual BOOL isItemRenameable() const { return TRUE; }
+ virtual BOOL isMultiPreviewAllowed() { return TRUE; }
//virtual BOOL renameItem(const std::string& new_name) {}
virtual BOOL isItemRemovable() const;
virtual BOOL isItemMovable() const;
@@ -136,6 +138,7 @@ public:
std::string& tooltip_msg) { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; }
EInventorySortGroup getSortGroup() const { return SG_ITEM; }
virtual LLInventoryObject* getInventoryObject() const;
@@ -605,6 +608,31 @@ protected:
static std::string sPrefix;
};
+
+class LLSettingsBridge : public LLItemBridge
+{
+public:
+ LLSettingsBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid,
+ LLSettingsType::type_e settings_type);
+ virtual LLUIImagePtr getIcon() const;
+ virtual void performAction(LLInventoryModel* model, std::string action);
+ virtual void openItem();
+ virtual BOOL isMultiPreviewAllowed() { return FALSE; }
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+ virtual BOOL renameItem(const std::string& new_name);
+ virtual BOOL isItemRenameable() const;
+ virtual LLSettingsType::type_e getSettingsType() const { return mSettingsType; }
+
+protected:
+ bool canUpdateRegion() const;
+ bool canUpdateParcel() const;
+
+ LLSettingsType::type_e mSettingsType;
+
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction
//
@@ -732,7 +760,7 @@ class LLFolderViewGroupedItemBridge: public LLFolderViewGroupedItemModel
public:
LLFolderViewGroupedItemBridge();
virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu);
- bool canWearSelected(uuid_vec_t item_ids);
+ bool canWearSelected(const uuid_vec_t& item_ids) const;
};
#endif // LL_LLINVENTORYBRIDGE_H
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index e8bc915f22..411311bbea 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -53,6 +53,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
: mFilterObjectTypes(p.object_types),
mFilterCategoryTypes(p.category_types),
mFilterWearableTypes(p.wearable_types),
+ mFilterSettingsTypes(p.settings_types),
mMinDate(p.date_range.min_date),
mMaxDate(p.date_range.max_date),
mHoursAgo(p.hours_ago),
@@ -62,7 +63,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
mPermissions(p.permissions),
mFilterTypes(p.types),
mFilterUUID(p.uuid),
- mFilterLinks(p.links)
+ mFilterLinks(p.links),
+ mSearchVisibility(p.search_visibility)
{
}
@@ -73,6 +75,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
: mName(p.name),
mFilterModified(FILTER_NONE),
mEmptyLookupMessage("InventoryNoMatchingItems"),
+ mDefaultEmptyLookupMessage(""),
mFilterOps(p.filter_ops),
mBackupFilterOps(mFilterOps),
mFilterSubString(p.substring),
@@ -153,6 +156,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
passed = passed && checkAgainstPermissions(listener);
passed = passed && checkAgainstFilterLinks(listener);
passed = passed && checkAgainstCreator(listener);
+ passed = passed && checkAgainstSearchVisibility(listener);
return passed;
}
@@ -191,10 +195,15 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
// when applying a filter, matching folders get their contents downloaded first
// but make sure we are not interfering with pre-download
if (isNotDefault()
- && !gInventory.isCategoryComplete(folder_id)
&& LLStartUp::getStartupState() > STATE_WEARABLES_WAIT)
- {
- LLInventoryModelBackgroundFetch::instance().start(folder_id);
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id);
+ if (!cat || (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN))
+ {
+ // At the moment background fetch only cares about VERSION_UNKNOWN,
+ // so do not check isCategoryComplete that compares descendant count
+ LLInventoryModelBackgroundFetch::instance().start(folder_id);
+ }
}
// Marketplace folder filtering
@@ -286,21 +295,34 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
// Pass if this item's type is of the correct filter type
if (filterTypes & FILTERTYPE_OBJECT)
{
-
- // If it has no type, pass it, unless it's a link.
- if (object_type == LLInventoryType::IT_NONE)
- {
- if (object && object->getIsLinkType())
- {
- return FALSE;
- }
- }
- else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
- {
- return FALSE;
- }
+ switch (object_type)
+ {
+ case LLInventoryType::IT_NONE:
+ // If it has no type, pass it, unless it's a link.
+ if (object && object->getIsLinkType())
+ {
+ return FALSE;
+ }
+ break;
+ case LLInventoryType::IT_UNKNOWN:
+ {
+ // Unknows are only shown when we show every type.
+ // Unknows are 255 and won't fit in 64 bits.
+ if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL)
+ {
+ return FALSE;
+ }
+ break;
+ }
+ default:
+ if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
+ {
+ return FALSE;
+ }
+ break;
+ }
}
-
+
if(filterTypes & FILTERTYPE_WORN)
{
if (!get_is_item_worn(object_id))
@@ -357,7 +379,21 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
if (filterTypes & FILTERTYPE_WEARABLE)
{
LLWearableType::EType type = listener->getWearableType();
- if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
+ if ((object_type == LLInventoryType::IT_WEARABLE) &&
+ (((0x1LL << type) & mFilterOps.mFilterWearableTypes) == 0))
+ {
+ return FALSE;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // FILTERTYPE_SETTINGS
+ // Pass if this item is a setting of the appropriate type
+ if (filterTypes & FILTERTYPE_SETTINGS)
+ {
+ LLSettingsType::type_e type = listener->getSettingsType();
+ if ((object_type == LLInventoryType::IT_SETTINGS) &&
+ (((0x1LL << type) & mFilterOps.mFilterSettingsTypes) == 0))
{
return FALSE;
}
@@ -411,18 +447,32 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons
// Pass if this item's type is of the correct filter type
if (filterTypes & FILTERTYPE_OBJECT)
{
- // If it has no type, pass it, unless it's a link.
- if (object_type == LLInventoryType::IT_NONE)
- {
- if (item && item->getIsLinkType())
- {
- return false;
- }
- }
- else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
- {
- return false;
- }
+ switch (object_type)
+ {
+ case LLInventoryType::IT_NONE:
+ // If it has no type, pass it, unless it's a link.
+ if (item && item->getIsLinkType())
+ {
+ return FALSE;
+ }
+ break;
+ case LLInventoryType::IT_UNKNOWN:
+ {
+ // Unknows are only shown when we show every type.
+ // Unknows are 255 and won't fit in 64 bits.
+ if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL)
+ {
+ return FALSE;
+ }
+ break;
+ }
+ default:
+ if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
+ {
+ return FALSE;
+ }
+ break;
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -535,6 +585,27 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
}
}
+bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItemInventory* listener) const
+{
+ if (!listener || !hasFilterString()) return TRUE;
+
+ const LLUUID object_id = listener->getUUID();
+ const LLInventoryObject *object = gInventory.getObject(object_id);
+ if (!object) return TRUE;
+
+ const BOOL is_link = object->getIsLinkType();
+ if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0))
+ return FALSE;
+
+ if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0))
+ return FALSE;
+
+ if (!listener->isAgentInventory() && ((mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY) == 0))
+ return FALSE;
+
+ return TRUE;
+}
+
const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
{
return mFilterSubString;
@@ -658,6 +729,12 @@ void LLInventoryFilter::setFilterWearableTypes(U64 types)
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
}
+void LLInventoryFilter::setFilterSettingsTypes(U64 types)
+{
+ updateFilterTypes(types, mFilterOps.mFilterSettingsTypes);
+ mFilterOps.mFilterTypes |= FILTERTYPE_SETTINGS;
+}
+
void LLInventoryFilter::setFilterEmptySystemFolders()
{
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
@@ -697,6 +774,61 @@ void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_list
}
}
+
+void LLInventoryFilter::toggleSearchVisibilityLinks()
+{
+ bool hide_links = mFilterOps.mSearchVisibility & VISIBILITY_LINKS;
+ if (hide_links)
+ {
+ mFilterOps.mSearchVisibility &= ~VISIBILITY_LINKS;
+ }
+ else
+ {
+ mFilterOps.mSearchVisibility |= VISIBILITY_LINKS;
+ }
+
+ if (hasFilterString())
+ {
+ setModified(hide_links ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+ }
+}
+
+void LLInventoryFilter::toggleSearchVisibilityTrash()
+{
+ bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH;
+ if (hide_trash)
+ {
+ mFilterOps.mSearchVisibility &= ~VISIBILITY_TRASH;
+ }
+ else
+ {
+ mFilterOps.mSearchVisibility |= VISIBILITY_TRASH;
+ }
+
+ if (hasFilterString())
+ {
+ setModified(hide_trash ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+ }
+}
+
+void LLInventoryFilter::toggleSearchVisibilityLibrary()
+{
+ bool hide_library = mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY;
+ if (hide_library)
+ {
+ mFilterOps.mSearchVisibility &= ~VISIBILITY_LIBRARY;
+ }
+ else
+ {
+ mFilterOps.mSearchVisibility |= VISIBILITY_LIBRARY;
+ }
+
+ if (hasFilterString())
+ {
+ setModified(hide_library ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+ }
+}
+
void LLInventoryFilter::setFilterNoMarketplaceFolder()
{
mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS;
@@ -808,6 +940,44 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
}
}
+void LLInventoryFilter::setSearchVisibilityTypes(U32 types)
+{
+ if (mFilterOps.mSearchVisibility != types)
+ {
+ // keep current items only if no perm bits getting turned off
+ BOOL fewer_bits_set = (mFilterOps.mSearchVisibility & ~types);
+ BOOL more_bits_set = (~mFilterOps.mSearchVisibility & types);
+ mFilterOps.mSearchVisibility = types;
+
+ if (more_bits_set && fewer_bits_set)
+ {
+ setModified(FILTER_RESTART);
+ }
+ else if (more_bits_set)
+ {
+ // target must have all requested permission bits, so more bits == more restrictive
+ setModified(FILTER_MORE_RESTRICTIVE);
+ }
+ else if (fewer_bits_set)
+ {
+ setModified(FILTER_LESS_RESTRICTIVE);
+ }
+ }
+}
+
+void LLInventoryFilter::setSearchVisibilityTypes(const Params& params)
+{
+ if (!params.validateBlock())
+ {
+ return;
+ }
+
+ if (params.filter_ops.search_visibility.isProvided())
+ {
+ setSearchVisibilityTypes(params.filter_ops.search_visibility);
+ }
+}
+
void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
{
if (mFilterOps.mPermissions != perms)
@@ -1209,6 +1379,18 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
+ if (isFilterObjectTypesWith(LLInventoryType::IT_SETTINGS))
+ {
+ filtered_types += LLTrans::getString("Settings");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ not_filtered_types += LLTrans::getString("Settings");
+ filtered_by_all_types = FALSE;
+ }
+
if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
&& filtered_by_type
&& !filtered_by_all_types)
@@ -1264,6 +1446,7 @@ void LLInventoryFilter::toParams(Params& params) const
params.filter_ops.show_folder_state = getShowFolderState();
params.filter_ops.creator_type = getFilterCreatorType();
params.filter_ops.permissions = getFilterPermissions();
+ params.filter_ops.search_visibility = getSearchVisibilityTypes();
params.substring = getFilterSubString();
params.since_logoff = isSinceLogoff();
}
@@ -1287,6 +1470,7 @@ void LLInventoryFilter::fromParams(const Params& params)
setShowFolderState(params.filter_ops.show_folder_state);
setFilterCreator(params.filter_ops.creator_type);
setFilterPermissions(params.filter_ops.permissions);
+ setSearchVisibilityTypes(params.filter_ops.search_visibility);
setFilterSubString(params.substring);
setDateRangeLastLogoff(params.since_logoff);
}
@@ -1311,6 +1495,16 @@ U64 LLInventoryFilter::getFilterWearableTypes() const
return mFilterOps.mFilterWearableTypes;
}
+U64 LLInventoryFilter::getFilterSettingsTypes() const
+{
+ return mFilterOps.mFilterSettingsTypes;
+}
+
+U64 LLInventoryFilter::getSearchVisibilityTypes() const
+{
+ return mFilterOps.mSearchVisibility;
+}
+
bool LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;
@@ -1383,12 +1577,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
mEmptyLookupMessage = message;
}
+void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message)
+{
+ mDefaultEmptyLookupMessage = message;
+}
+
std::string LLInventoryFilter::getEmptyLookupMessage() const
{
- LLStringUtil::format_map_t args;
- args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+ if (isDefault() && !mDefaultEmptyLookupMessage.empty())
+ {
+ return LLTrans::getString(mDefaultEmptyLookupMessage);
+ }
+ else
+ {
+ LLStringUtil::format_map_t args;
+ args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
- return LLTrans::getString(mEmptyLookupMessage, args);
+ return LLTrans::getString(mEmptyLookupMessage, args);
+ }
}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 3f24211f41..384de3e889 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -59,6 +59,7 @@ public:
FILTERTYPE_MARKETPLACE_LISTING_FOLDER = 0x1 << 9, // pass iff folder is a listing folder
FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10, // pass iff folder is not under the marketplace
FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn
+ FILTERTYPE_SETTINGS = 0x1 << 12, // pass if the item is a settings object
};
enum EFilterDateDirection
@@ -80,7 +81,7 @@ public:
SO_DATE = 0x1, // Sort inventory by date
SO_FOLDERS_BY_NAME = 0x1 << 1, // Force folder sort by name
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2,// Force system folders to be on top
- SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendents
+ SO_FOLDERS_BY_WEIGHT = 0x1 << 3, // Force folder sort by weight, usually, amount of some elements in their descendants
};
enum ESearchType
@@ -98,6 +99,14 @@ public:
FILTERCREATOR_OTHERS
};
+ enum ESearchVisibility
+ {
+ VISIBILITY_NONE = 0,
+ VISIBILITY_TRASH = 0x1 << 0,
+ VISIBILITY_LIBRARY = 0x1 << 1,
+ VISIBILITY_LINKS = 0x1 << 2
+ };
+
struct FilterOps
{
struct DateRange : public LLInitParam::Block<DateRange>
@@ -115,10 +124,13 @@ public:
struct Params : public LLInitParam::Block<Params>
{
- Optional<U32> types;
+ Optional<U32> types,
+ search_visibility;
Optional<U64> object_types,
wearable_types,
+ settings_types,
category_types;
+
Optional<EFilterLink> links;
Optional<LLUUID> uuid;
Optional<DateRange> date_range;
@@ -132,8 +144,10 @@ public:
: types("filter_types", FILTERTYPE_OBJECT),
object_types("object_types", 0xffffFFFFffffFFFFULL),
wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
+ settings_types("settings_types", 0xffffFFFFffffFFFFULL),
category_types("category_types", 0xffffFFFFffffFFFFULL),
links("links", FILTERLINK_INCLUDE_LINKS),
+ search_visibility("search_visibility", 0xFFFFFFFF),
uuid("uuid"),
date_range("date_range"),
hours_ago("hours_ago", 0),
@@ -146,9 +160,11 @@ public:
FilterOps(const Params& = Params());
- U32 mFilterTypes;
+ U32 mFilterTypes,
+ mSearchVisibility;
U64 mFilterObjectTypes, // For _OBJECT
mFilterWearableTypes,
+ mFilterSettingsTypes, // for _SETTINGS
mFilterLinks,
mFilterCategoryTypes; // For _CATEGORY
LLUUID mFilterUUID; // for UUID
@@ -158,8 +174,8 @@ public:
U32 mHoursAgo;
U32 mDateSearchDirection;
- EFolderShow mShowFolderState;
- PermissionMask mPermissions;
+ EFolderShow mShowFolderState;
+ PermissionMask mPermissions;
EFilterCreatorType mFilterCreatorType;
};
@@ -189,11 +205,15 @@ public:
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
U64 getFilterWearableTypes() const;
+ U64 getFilterSettingsTypes() const;
+ U64 getSearchVisibilityTypes() const;
+
bool isFilterObjectTypesWith(LLInventoryType::EType t) const;
void setFilterObjectTypes(U64 types);
void setFilterCategoryTypes(U64 types);
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
+ void setFilterSettingsTypes(U64 types);
void setFilterEmptySystemFolders();
void setFilterWorn();
void setFilterMarketplaceActiveFolders();
@@ -206,6 +226,12 @@ public:
ESearchType getSearchType() { return mSearchType; }
void setFilterCreator(EFilterCreatorType type);
+ void toggleSearchVisibilityLinks();
+ void toggleSearchVisibilityTrash();
+ void toggleSearchVisibilityLibrary();
+ void setSearchVisibilityTypes(U32 types);
+ void setSearchVisibilityTypes(const Params& params);
+
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
@@ -245,11 +271,12 @@ public:
// +-------------------------------------------------------------------+
// + Presentation
// +-------------------------------------------------------------------+
- void setShowFolderState( EFolderShow state);
- EFolderShow getShowFolderState() const;
+ void setShowFolderState( EFolderShow state);
+ EFolderShow getShowFolderState() const;
EFilterCreatorType getFilterCreatorType() const;
void setEmptyLookupMessage(const std::string& message);
+ void setDefaultEmptyLookupMessage(const std::string& message);
std::string getEmptyLookupMessage() const;
// +-------------------------------------------------------------------+
@@ -302,6 +329,7 @@ private:
bool checkAgainstPermissions(const LLInventoryItem* item) const;
bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
bool checkAgainstCreator(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstSearchVisibility(const class LLFolderViewModelItemInventory* listener) const;
bool checkAgainstClipboard(const LLUUID& object_id) const;
FilterOps mFilterOps;
@@ -325,6 +353,7 @@ private:
std::string mFilterText;
std::string mEmptyLookupMessage;
+ std::string mDefaultEmptyLookupMessage;
ESearchType mSearchType;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 030c967019..f2e06d19f3 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -78,6 +78,7 @@
#include "lltooldraganddrop.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
+#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewerfoldertype.h"
#include "llviewerobjectlist.h"
@@ -655,6 +656,50 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
return TRUE;
}
+bool get_is_item_editable(const LLUUID& inv_item_id)
+{
+ if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
+ {
+ switch (inv_item->getType())
+ {
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_CLOTHING:
+ return gAgentWearables.isWearableModifiable(inv_item_id);
+ case LLAssetType::AT_OBJECT:
+ return true;
+ default:
+ return false;;
+ }
+ }
+ return gAgentAvatarp->getWornAttachment(inv_item_id) != nullptr;
+}
+
+void handle_item_edit(const LLUUID& inv_item_id)
+{
+ if (get_is_item_editable(inv_item_id))
+ {
+ if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
+ {
+ switch (inv_item->getType())
+ {
+ case LLAssetType::AT_BODYPART:
+ case LLAssetType::AT_CLOTHING:
+ LLAgentWearables::editWearable(inv_item_id);
+ break;
+ case LLAssetType::AT_OBJECT:
+ handle_attachment_edit(inv_item_id);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ handle_attachment_edit(inv_item_id);
+ }
+ }
+}
+
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
{
// NOTE: This function doesn't check the folder's children.
@@ -729,40 +774,45 @@ void show_item_profile(const LLUUID& item_uuid)
void show_item_original(const LLUUID& item_uuid)
{
- LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
- if (!floater_inventory)
- {
- LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
- return;
- }
-
- //sidetray inventory panel
- LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
-
- bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain();
+ 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)
+ {
+ LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
+ if (main_inventory)
+ {
+ main_inventory->resetFilters();
+ }
+ reset_inventory_filter();
- LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
- if (!active_panel)
- {
- //this may happen when there is no floatera and other panel is active in inventory tab
+ if (!LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("inventory")->isInVisibleChain())
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("inventory");
+ }
- if (sidepanel_inventory)
- {
- sidepanel_inventory->showInventoryPanel();
- }
- }
-
- active_panel = LLInventoryPanel::getActiveInventoryPanel();
- if (!active_panel)
- {
- return;
- }
- active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
-
- if(do_reset_inventory_filter)
- {
- reset_inventory_filter();
- }
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+ if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id))
+ {
+ if (sidepanel_inventory->getInboxPanel())
+ {
+ sidepanel_inventory->openInbox();
+ sidepanel_inventory->getInboxPanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
+ }
+ }
+ else
+ {
+ sidepanel_inventory->selectAllItemsPanel();
+ if (sidepanel_inventory->getActivePanel())
+ {
+ sidepanel_inventory->getActivePanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
+ }
+ }
+ }
}
@@ -1797,6 +1847,26 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
return result && !has_bad_items;
}
+void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
+{
+ LLInventoryItem* inv_item = gInventory.getItem(item_id);
+ if (inv_item)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
+ new_item->setParent(new_parent_id);
+ new_item->updateParentOnServer(FALSE);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -2395,10 +2465,32 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
if (("task_open" == action || "open" == action) && selected_items.size() > 1)
{
- multi_previewp = new LLMultiPreview();
- gFloaterView->addChild(multi_previewp);
+ bool open_multi_preview = true;
- LLFloater::setFloaterHost(multi_previewp);
+ if ("open" == action)
+ {
+ for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = *set_iter;
+ if (folder_item)
+ {
+ LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem());
+ if (!bridge || !bridge->isMultiPreviewAllowed())
+ {
+ open_multi_preview = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (open_multi_preview)
+ {
+ multi_previewp = new LLMultiPreview();
+ gFloaterView->addChild(multi_previewp);
+
+ LLFloater::setFloaterHost(multi_previewp);
+ }
}
else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index fd106bc2d8..37c3c47336 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -53,6 +53,10 @@ BOOL get_can_item_be_worn(const LLUUID& id);
BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id);
+// Performs the appropiate edit action (if one exists) for this item
+bool get_is_item_editable(const LLUUID& inv_item_id);
+void handle_item_edit(const LLUUID& inv_item_id);
+
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
@@ -88,6 +92,8 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid);
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);
+
/** Miscellaneous global functions
** **
*******************************************************************************/
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index ee6e3dd384..81c001b8bd 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -34,6 +34,7 @@
#include "llui.h"
#include "lluiimage.h"
#include "llwearabletype.h"
+#include "llinventorysettings.h"
struct IconEntry : public LLDictionaryEntry
{
@@ -93,6 +94,11 @@ LLIconDictionary::LLIconDictionary()
addEntry(LLInventoryType::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkFolder"));
addEntry(LLInventoryType::ICONNAME_MESH, new IconEntry("Inv_Mesh"));
+ addEntry(LLInventoryType::ICONNAME_SETTINGS_SKY, new IconEntry("Inv_SettingsSky"));
+ addEntry(LLInventoryType::ICONNAME_SETTINGS_WATER, new IconEntry("Inv_SettingsWater"));
+ addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay"));
+ addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings"));
+
addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown"));
@@ -168,6 +174,9 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
break;
case LLAssetType::AT_MESH:
idx = LLInventoryType::ICONNAME_MESH;
+ case LLAssetType::AT_SETTINGS:
+ idx = assignSettingsIcon(misc_flag);
+ break;
case LLAssetType::AT_UNKNOWN:
idx = LLInventoryType::ICONNAME_UNKNOWN;
default:
@@ -189,3 +198,9 @@ LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
const LLWearableType::EType wearable_type = LLWearableType::inventoryFlagsToWearableType(misc_flag);
return LLWearableType::getIconName(wearable_type);
}
+
+LLInventoryType::EIconName LLInventoryIcon::assignSettingsIcon(U32 misc_flag)
+{
+ LLSettingsType::type_e settings_type = LLSettingsType::fromInventoryFlags(misc_flag);
+ return LLSettingsType::getIconName(settings_type);
+}
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index bc09e32087..b8637c4e33 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -48,6 +48,7 @@ public:
protected:
static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
+ static LLInventoryType::EIconName assignSettingsIcon(U32 misc_flag);
};
#endif // LL_LLINVENTORYICON_H
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c49d61df31..28db6a5808 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -56,6 +56,7 @@
#include "llcallbacklist.h"
#include "llvoavatarself.h"
#include "llgesturemgr.h"
+#include "llsdserialize.h"
#include "llsdutil.h"
#include "bufferarray.h"
#include "bufferstream.h"
@@ -76,8 +77,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
///----------------------------------------------------------------------------
//BOOL decompress_file(const char* src_filename, const char* dst_filename);
-static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv";
-static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv";
+static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv.llsd";
+static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv.llsd";
static const char * const LOG_INV("Inventory");
struct InventoryIDPtrLess
@@ -678,17 +679,59 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
LLUUID categoryId = result["folder_id"].asUUID();
- // Add the category to the internal representation
- LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
- result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
- result["name"].asString(), gAgent.getID());
+ LLViewerInventoryCategory* folderp = gInventory.getCategory(categoryId);
+ if (!folderp)
+ {
+ // Add the category to the internal representation
+ LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+ result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+ result["name"].asString(), gAgent.getID());
- cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
- cat->setDescendentCount(0);
- LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
-
- accountForUpdate(update);
- updateCategory(cat);
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ accountForUpdate(update);
+
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+ cat->setDescendentCount(0);
+ updateCategory(cat);
+ }
+ else
+ {
+ // bulk processing was faster than coroutine (coro request->processBulkUpdateInventory->coro response)
+ // category already exists, but needs an update
+ if (folderp->getVersion() != LLViewerInventoryCategory::VERSION_INITIAL
+ || folderp->getDescendentCount() != LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
+ {
+ LL_WARNS() << "Inventory desync on folder creation. Newly created folder already has descendants or got a version.\n"
+ << "Name: " << folderp->getName()
+ << " Id: " << folderp->getUUID()
+ << " Version: " << folderp->getVersion()
+ << " Descendants: " << folderp->getDescendentCount()
+ << LL_ENDL;
+ }
+ // Recreate category with correct values
+ // Creating it anew just simplifies figuring out needed change-masks
+ // and making all needed updates, see updateCategory
+ LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+ result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+ result["name"].asString(), gAgent.getID());
+
+ if (folderp->getParentUUID() != cat->getParentUUID())
+ {
+ LL_WARNS() << "Inventory desync on folder creation. Newly created folder has wrong parent.\n"
+ << "Name: " << folderp->getName()
+ << " Id: " << folderp->getUUID()
+ << " Expected parent: " << cat->getParentUUID()
+ << " Actual parent: " << folderp->getParentUUID()
+ << LL_ENDL;
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+ accountForUpdate(update);
+ }
+ // else: Do not update parent, parent is already aware of the change. See processBulkUpdateInventory
+
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+ cat->setDescendentCount(0);
+ updateCategory(cat);
+ }
if (callback)
{
@@ -888,6 +931,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
return mask;
}
+ if (item->getType() == LLAssetType::AT_MESH)
+ {
+ return mask;
+ }
+
LLPointer<LLViewerInventoryItem> old_item = getItem(item->getUUID());
LLPointer<LLViewerInventoryItem> new_item;
if(old_item)
@@ -898,16 +946,29 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
LLUUID new_parent_id = item->getParentUUID();
bool update_parent_on_server = false;
- if (new_parent_id.isNull())
+ if (new_parent_id.isNull() && !LLApp::isExiting())
{
- // item with null parent will end in random location and then in Lost&Found,
- // either move to default folder as if it is new item or don't move at all
- LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
- << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
- << ". New name: " << item->getName()
- << "." << LL_ENDL;
- new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- update_parent_on_server = true;
+ if (old_parent_id.isNull())
+ {
+ // Item with null parent will end in random location and then in Lost&Found,
+ // either move to default folder as if it is new item or don't move at all
+ LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
+ << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
+ << ". New name: " << item->getName()
+ << "." << LL_ENDL;
+ new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+ update_parent_on_server = true;
+ }
+ else
+ {
+ // Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point
+ LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
+ << " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName()
+ << ". New name: " << item->getName()
+ << "." << LL_ENDL;
+ new_parent_id = old_parent_id;
+ update_parent_on_server = true;
+ }
}
if(old_parent_id != new_parent_id)
@@ -1810,7 +1871,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
return;
}
- if (LLAssetType::lookup(item->getType()) == LLAssetType::badLookup())
+ if (LLAssetType::lookup(item->getType()) == LLAssetType::BADLOOKUP)
{
if (item->getType() >= LLAssetType::AT_COUNT)
{
@@ -2599,6 +2660,7 @@ void LLInventoryModel::createCommonSystemCategories()
gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD,true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS,true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS, true);
}
struct LLUUIDAndName
@@ -2642,29 +2704,37 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
{
if(filename.empty())
{
- LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
+ LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
return false;
}
- LL_INFOS(LOG_INV) << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL;
- LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
- if(!file)
+ LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
+
+ llifstream file(filename.c_str());
+
+ if (!file.is_open())
{
LL_INFOS(LOG_INV) << "unable to load inventory from: " << filename << LL_ENDL;
return false;
}
- // *NOTE: This buffer size is hard coded into scanf() below.
- char buffer[MAX_STRING]; /*Flawfinder: ignore*/
- char keyword[MAX_STRING]; /*Flawfinder: ignore*/
- char value[MAX_STRING]; /*Flawfinder: ignore*/
- is_cache_obsolete = true; // Obsolete until proven current
- while(!feof(file) && fgets(buffer, MAX_STRING, file))
+
+ is_cache_obsolete = true; // Obsolete until proven current
+
+ std::string line;
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
+ while (std::getline(file, line))
{
- sscanf(buffer, " %126s %126s", keyword, value); /* Flawfinder: ignore */
- if(0 == strcmp("inv_cache_version", keyword))
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL;
+ break;
+ }
+
+ if (s_item.has("inv_cache_version"))
{
- S32 version;
- int succ = sscanf(value,"%d",&version);
- if ((1 == succ) && (version == sCurrentInvCacheVersion))
+ S32 version = s_item["inv_cache_version"].asInteger();
+ if (version == sCurrentInvCacheVersion)
{
// Cache is up to date
is_cache_obsolete = false;
@@ -2672,43 +2742,33 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
else
{
- // Cache is out of date
+ LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL;
break;
}
}
- else if(0 == strcmp("inv_category", keyword))
+ else if (s_item.has("cat_id"))
{
if (is_cache_obsolete)
break;
-
+
LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
- if(inv_cat->importFileLocal(file))
+ if(inv_cat->importLLSD(s_item))
{
categories.push_back(inv_cat);
}
- else
- {
- LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL;
- //delete inv_cat; // automatic when inv_cat is reassigned or destroyed
- }
}
- else if(0 == strcmp("inv_item", keyword))
+ else if (s_item.has("item_id"))
{
if (is_cache_obsolete)
break;
LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
- if( inv_item->importFileLocal(file) )
+ if( inv_item->fromLLSD(s_item) )
{
- // *FIX: Need a better solution, this prevents the
- // application from freezing, but breaks inventory
- // caching.
if(inv_item->getUUID().isNull())
{
- //delete inv_item; // automatic when inv_cat is reassigned or destroyed
LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
- << inv_item->getName() << LL_ENDL;
-
+ << inv_item->getName() << LL_ENDL;
}
else
{
@@ -2721,62 +2781,63 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
items.push_back(inv_item);
}
}
- }
- else
- {
- LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL;
- //delete inv_item; // automatic when inv_cat is reassigned or destroyed
- }
- }
- else
- {
- LL_WARNS(LOG_INV) << "Unknown token in inventory file '" << keyword << "'"
- << LL_ENDL;
+ }
}
}
- fclose(file);
- if (is_cache_obsolete)
- return false;
- return true;
+
+ file.close();
+
+ return !is_cache_obsolete;
}
// static
bool LLInventoryModel::saveToFile(const std::string& filename,
- const cat_array_t& categories,
- const item_array_t& items)
+ const cat_array_t& categories,
+ const item_array_t& items)
{
- if(filename.empty())
+ if (filename.empty())
{
LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
return false;
}
- LL_INFOS(LOG_INV) << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL;
- LLFILE* file = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/
- if(!file)
+
+ LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL;
+
+ llofstream fileXML(filename.c_str());
+ if (!fileXML.is_open())
{
LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL;
return false;
}
- fprintf(file, "\tinv_cache_version\t%d\n",sCurrentInvCacheVersion);
+ LLSD cache_ver;
+ cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
+
+ fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
+
S32 count = categories.size();
+ S32 cat_count = 0;
S32 i;
for(i = 0; i < count; ++i)
{
LLViewerInventoryCategory* cat = categories[i];
if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
{
- cat->exportFileLocal(file);
+ fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
+ cat_count++;
}
}
- count = items.size();
- for(i = 0; i < count; ++i)
+ S32 it_count = items.size();
+ for(i = 0; i < it_count; ++i)
{
- items[i]->exportFile(file);
+ fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
}
- fclose(file);
+ fileXML.close();
+
+ LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
+
return true;
}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d4993a1091..3608f9e23f 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -46,12 +46,19 @@
#include "llnotificationsutil.h"
#include "llpreview.h"
#include "llsidepanelinventory.h"
+#include "llstartup.h"
#include "lltrans.h"
+#include "llviewerassettype.h"
#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
#include "llvoavatarself.h"
+class LLInventoryRecentItemsPanel;
+class LLAssetFilteredInventoryPanel;
+
static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
+static LLDefaultChildRegistry::Register<LLInventoryRecentItemsPanel> t_recent_inventory_panel("recent_inventory_panel");
+static LLDefaultChildRegistry::Register<LLAssetFilteredInventoryPanel> t_asset_filtered_inv_panel("asset_filtered_inv_panel");
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
@@ -139,15 +146,20 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCompletionObserver(NULL),
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
- mInventory(p.inventory),
+ mInventory(p.inventory), //inventory("", &gInventory)
mAcceptsDragAndDrop(p.accepts_drag_and_drop),
mAllowMultiSelect(p.allow_multi_select),
+ mAllowDrag(p.allow_drag),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowEmptyMessage(p.show_empty_message),
- mViewsInitialized(false),
+ mSuppressFolderMenu(p.suppress_folder_menu),
+ mSuppressOpenItemAction(false),
+ mBuildViewsOnInit(p.preinitialize_views),
+ mViewsInitialized(VIEWS_UNINITIALIZED),
mInvFVBridgeBuilder(NULL),
mInventoryViewModel(p.name),
- mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
+ mGroupedItemBridge(new LLFolderViewGroupedItemBridge),
+ mFocusSelection(false)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@@ -190,7 +202,9 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
p.grouped_item_model = mGroupedItemBridge;
p.use_label_suffix = mParams.use_label_suffix;
p.allow_multiselect = mAllowMultiSelect;
+ p.allow_drag = mAllowDrag;
p.show_empty_message = mShowEmptyMessage;
+ p.suppress_folder_menu = mSuppressFolderMenu;
p.show_item_link_overlays = mShowItemLinkOverlays;
p.root = NULL;
p.allow_drop = mParams.allow_drop_on_root;
@@ -269,14 +283,22 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
mInventory->addObserver(mCompletionObserver);
- // Build view of inventory if we need default full hierarchy and inventory ready,
- // otherwise wait for idle callback.
- if (mInventory->isInventoryUsable() && !mViewsInitialized)
- {
- initializeViews();
- }
-
- gIdleCallbacks.addFunction(onIdle, (void*)this);
+ if (mBuildViewsOnInit)
+ {
+ // Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle.
+ // Initializing views takes a while so always do it onIdle if viewer already loaded.
+ if (mInventory->isInventoryUsable()
+ && mViewsInitialized == VIEWS_UNINITIALIZED
+ && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
+ {
+ initializeViews();
+ }
+ else if (mViewsInitialized != VIEWS_INITIALIZING)
+ {
+ mViewsInitialized = VIEWS_INITIALIZING;
+ gIdleCallbacks.addFunction(onIdle, (void*)this);
+ }
+ }
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
@@ -291,7 +313,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
{
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
}
// hide marketplace listing box, unless we are a marketplace panel
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible") && !mParams.use_marketplace_folders)
@@ -323,6 +344,17 @@ LLInventoryPanel::~LLInventoryPanel()
clearFolderRoot();
}
+/*virtual*/
+void LLInventoryPanel::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility && mViewsInitialized == VIEWS_UNINITIALIZED)
+ {
+ mViewsInitialized = VIEWS_INITIALIZING;
+ gIdleCallbacks.addFunction(onIdle, (void*)this);
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
void LLInventoryPanel::draw()
{
// Select the desired item (in case it wasn't loaded when the selection was requested)
@@ -377,6 +409,11 @@ void LLInventoryPanel::setFilterWearableTypes(U64 types)
getFilter().setFilterWearableTypes(types);
}
+void LLInventoryPanel::setFilterSettingsTypes(U64 filter)
+{
+ getFilter().setFilterSettingsTypes(filter);
+}
+
void LLInventoryPanel::setFilterSubString(const std::string& string)
{
getFilter().setFilterSubString(string);
@@ -387,7 +424,6 @@ const std::string LLInventoryPanel::getFilterSubString()
return getFilter().getFilterSubString();
}
-
void LLInventoryPanel::setSortOrder(U32 order)
{
LLInventorySort sorter(order);
@@ -445,195 +481,218 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
return getFilter().getShowFolderState();
}
-// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849)
-static LLTrace::BlockTimerStatHandle FTM_REFRESH("Inventory Refresh");
-void LLInventoryPanel::modelChanged(U32 mask)
+void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item)
{
- LL_RECORD_BLOCK_TIME(FTM_REFRESH);
+ LLFolderViewItem* view_item = getItemByID(item_id);
+ LLFolderViewModelItemInventory* viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
- if (!mViewsInitialized) return;
-
- const LLInventoryModel* model = getModel();
- if (!model) return;
+ // LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
+ // to folder is the fast way to get a folder without searching through folders tree.
+ LLFolderViewFolder* view_folder = NULL;
- const LLInventoryModel::changed_items_t& changed_items = model->getChangedIDs();
- if (changed_items.empty()) return;
+ // Check requires as this item might have already been deleted
+ // as a child of its deleted parent.
+ if (model_item && view_item)
+ {
+ view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+ }
- for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
- items_iter != changed_items.end();
- ++items_iter)
+ //////////////////////////////
+ // LABEL Operation
+ // Empty out the display name for relabel.
+ if (mask & LLInventoryObserver::LABEL)
{
- const LLUUID& item_id = (*items_iter);
- const LLInventoryObject* model_item = model->getObject(item_id);
- LLFolderViewItem* view_item = getItemByID(item_id);
- LLFolderViewModelItemInventory* viewmodel_item =
- static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
+ if (view_item)
+ {
+ // Request refresh on this item (also flags for filtering)
+ LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
+ if(bridge)
+ {
+ // Clear the display name first, so it gets properly re-built during refresh()
+ bridge->clearDisplayName();
- // LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
- // to folder is the fast way to get a folder without searching through folders tree.
- LLFolderViewFolder* view_folder = NULL;
+ view_item->refresh();
+ }
+ LLFolderViewFolder* parent = view_item->getParentFolder();
+ if(parent)
+ {
+ parent->getViewModelItem()->dirtyDescendantsFilter();
+ }
+ }
+ }
- // Check requires as this item might have already been deleted
- // as a child of its deleted parent.
- if (model_item && view_item)
+ //////////////////////////////
+ // REBUILD Operation
+ // Destroy and regenerate the UI.
+ if (mask & LLInventoryObserver::REBUILD)
+ {
+ if (model_item && view_item && viewmodel_item)
{
- view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+ const LLUUID& idp = viewmodel_item->getUUID();
+ view_item->destroyView();
+ removeItemID(idp);
}
- //////////////////////////////
- // LABEL Operation
- // Empty out the display name for relabel.
- if (mask & LLInventoryObserver::LABEL)
- {
- if (view_item)
- {
- // Request refresh on this item (also flags for filtering)
- LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
- if(bridge)
- { // Clear the display name first, so it gets properly re-built during refresh()
- bridge->clearDisplayName();
+ LLInventoryObject const* objectp = mInventory->getObject(item_id);
+ if (objectp)
+ {
+ // providing NULL directly avoids unnessesary getItemByID calls
+ view_item = buildNewViews(item_id, objectp, NULL);
+ }
+ else
+ {
+ view_item = NULL;
+ }
- view_item->refresh();
- }
- LLFolderViewFolder* parent = view_item->getParentFolder();
- if(parent)
- {
- parent->getViewModelItem()->dirtyDescendantsFilter();
- }
- }
+ viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
+ view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
+ }
+
+ //////////////////////////////
+ // INTERNAL Operation
+ // This could be anything. For now, just refresh the item.
+ if (mask & LLInventoryObserver::INTERNAL)
+ {
+ if (view_item)
+ {
+ view_item->refresh();
}
+ }
- //////////////////////////////
- // REBUILD Operation
- // Destroy and regenerate the UI.
- if (mask & LLInventoryObserver::REBUILD)
+ //////////////////////////////
+ // SORT Operation
+ // Sort the folder.
+ if (mask & LLInventoryObserver::SORT)
+ {
+ if (view_folder)
{
- if (model_item && view_item && viewmodel_item)
- {
- const LLUUID& idp = viewmodel_item->getUUID();
- view_item->destroyView();
- removeItemID(idp);
- }
- view_item = buildNewViews(item_id);
- viewmodel_item =
- static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
- view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
+ view_folder->getViewModelItem()->requestSort();
}
+ }
+ // We don't typically care which of these masks the item is actually flagged with, since the masks
+ // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into
+ // Landmarks; this is a STRUCTURE change for that panel but is an ADD change for the Landmarks
+ // panel). What's relevant is that the item and UI are probably out of sync and thus need to be
+ // resynchronized.
+ if (mask & (LLInventoryObserver::STRUCTURE |
+ LLInventoryObserver::ADD |
+ LLInventoryObserver::REMOVE))
+ {
//////////////////////////////
- // INTERNAL Operation
- // This could be anything. For now, just refresh the item.
- if (mask & LLInventoryObserver::INTERNAL)
+ // ADD Operation
+ // Item exists in memory but a UI element hasn't been created for it.
+ if (model_item && !view_item)
{
- if (view_item)
+ // Add the UI element for this item.
+ LLInventoryObject const* objectp = mInventory->getObject(item_id);
+ if (objectp)
+ {
+ // providing NULL directly avoids unnessesary getItemByID calls
+ buildNewViews(item_id, objectp, NULL);
+ }
+
+ // Select any newly created object that has the auto rename at top of folder root set.
+ if(mFolderRoot.get()->getRoot()->needsAutoRename())
{
- view_item->refresh();
+ setSelection(item_id, FALSE);
}
+ updateFolderLabel(model_item->getParentUUID());
}
//////////////////////////////
- // SORT Operation
- // Sort the folder.
- if (mask & LLInventoryObserver::SORT)
+ // STRUCTURE Operation
+ // This item already exists in both memory and UI. It was probably reparented.
+ else if (model_item && view_item)
{
- if (view_folder)
+ LLFolderViewFolder* old_parent = view_item->getParentFolder();
+ // Don't process the item if it is the root
+ if (old_parent)
{
- view_folder->getViewModelItem()->requestSort();
- }
- }
-
- // We don't typically care which of these masks the item is actually flagged with, since the masks
- // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into
- // Landmarks; this is a STRUCTURE change for that panel but is an ADD change for the Landmarks
- // panel). What's relevant is that the item and UI are probably out of sync and thus need to be
- // resynchronized.
- if (mask & (LLInventoryObserver::STRUCTURE |
- LLInventoryObserver::ADD |
- LLInventoryObserver::REMOVE))
- {
- //////////////////////////////
- // ADD Operation
- // Item exists in memory but a UI element hasn't been created for it.
- if (model_item && !view_item)
- {
- // Add the UI element for this item.
- buildNewViews(item_id);
- // Select any newly created object that has the auto rename at top of folder root set.
- if(mFolderRoot.get()->getRoot()->needsAutoRename())
- {
- setSelection(item_id, FALSE);
- }
- updateFolderLabel(model_item->getParentUUID());
- }
-
- //////////////////////////////
- // STRUCTURE Operation
- // This item already exists in both memory and UI. It was probably reparented.
- else if (model_item && view_item)
- {
- LLFolderViewFolder* old_parent = view_item->getParentFolder();
- // Don't process the item if it is the root
- if (old_parent)
+ LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(old_parent->getViewModelItem());
+ LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
+ // Item has been moved.
+ if (old_parent != new_parent)
{
- LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(old_parent->getViewModelItem());
- LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
- // Item has been moved.
- if (old_parent != new_parent)
+ if (new_parent != NULL)
{
- if (new_parent != NULL)
+ // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
+ view_item->addToFolder(new_parent);
+ addItemID(viewmodel_item->getUUID(), view_item);
+ if (mInventory)
{
- // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
- view_item->addToFolder(new_parent);
- addItemID(viewmodel_item->getUUID(), view_item);
- if (mInventory)
+ const LLUUID trash_id = mInventory->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id != model_item->getParentUUID() && (mask & LLInventoryObserver::INTERNAL) && new_parent->isOpen())
{
- const LLUUID trash_id = mInventory->findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if (trash_id != model_item->getParentUUID() && (mask & LLInventoryObserver::INTERNAL) && new_parent->isOpen())
- {
- setSelection(item_id, FALSE);
- }
+ setSelection(item_id, FALSE);
}
- updateFolderLabel(model_item->getParentUUID());
}
- else
- {
- // Remove the item ID before destroying the view because the view-model-item gets
- // destroyed when the view is destroyed
- removeItemID(viewmodel_item->getUUID());
+ updateFolderLabel(model_item->getParentUUID());
+ }
+ else
+ {
+ // Remove the item ID before destroying the view because the view-model-item gets
+ // destroyed when the view is destroyed
+ removeItemID(viewmodel_item->getUUID());
- // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
- // doesn't include trash). Just remove the item's UI.
- view_item->destroyView();
- }
- if(viewmodel_folder)
- {
- updateFolderLabel(viewmodel_folder->getUUID());
- }
- old_parent->getViewModelItem()->dirtyDescendantsFilter();
+ // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
+ // doesn't include trash). Just remove the item's UI.
+ view_item->destroyView();
}
- }
- }
-
- //////////////////////////////
- // REMOVE Operation
- // This item has been removed from memory, but its associated UI element still exists.
- else if (!model_item && view_item && viewmodel_item)
- {
- // Remove the item's UI.
- LLFolderViewFolder* parent = view_item->getParentFolder();
- removeItemID(viewmodel_item->getUUID());
- view_item->destroyView();
- if(parent)
- {
- parent->getViewModelItem()->dirtyDescendantsFilter();
- LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(parent->getViewModelItem());
if(viewmodel_folder)
{
updateFolderLabel(viewmodel_folder->getUUID());
}
+ old_parent->getViewModelItem()->dirtyDescendantsFilter();
}
}
}
+
+ //////////////////////////////
+ // REMOVE Operation
+ // This item has been removed from memory, but its associated UI element still exists.
+ else if (!model_item && view_item && viewmodel_item)
+ {
+ // Remove the item's UI.
+ LLFolderViewFolder* parent = view_item->getParentFolder();
+ removeItemID(viewmodel_item->getUUID());
+ view_item->destroyView();
+ if(parent)
+ {
+ parent->getViewModelItem()->dirtyDescendantsFilter();
+ LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(parent->getViewModelItem());
+ if(viewmodel_folder)
+ {
+ updateFolderLabel(viewmodel_folder->getUUID());
+ }
+ }
+ }
+ }
+}
+
+// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849)
+static LLTrace::BlockTimerStatHandle FTM_REFRESH("Inventory Refresh");
+void LLInventoryPanel::modelChanged(U32 mask)
+{
+ LL_RECORD_BLOCK_TIME(FTM_REFRESH);
+
+ if (mViewsInitialized != VIEWS_INITIALIZED) return;
+
+ const LLInventoryModel* model = getModel();
+ if (!model) return;
+
+ const LLInventoryModel::changed_items_t& changed_items = model->getChangedIDs();
+ if (changed_items.empty()) return;
+
+ for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
+ items_iter != changed_items.end();
+ ++items_iter)
+ {
+ const LLUUID& item_id = (*items_iter);
+ const LLInventoryObject* model_item = model->getObject(item_id);
+ itemChanged(item_id, mask, model_item);
}
}
@@ -685,11 +744,11 @@ void LLInventoryPanel::onIdle(void *userdata)
LLInventoryPanel *self = (LLInventoryPanel*)userdata;
// Inventory just initialized, do complete build
- if (!self->mViewsInitialized)
+ if (self->mViewsInitialized != VIEWS_INITIALIZED)
{
self->initializeViews();
}
- if (self->mViewsInitialized)
+ if (self->mViewsInitialized == VIEWS_INITIALIZED)
{
gIdleCallbacks.deleteFunction(onIdle, (void*)self);
}
@@ -772,7 +831,7 @@ void LLInventoryPanel::initializeViews()
gIdleCallbacks.addFunction(idle, this);
- mViewsInitialized = true;
+ mViewsInitialized = VIEWS_INITIALIZED;
openStartFolderOrMyInventory();
@@ -831,18 +890,53 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
- LLInventoryObject const* objectp = gInventory.getObject(id);
-
- if (!objectp)
+ LLInventoryObject const* objectp = mInventory->getObject(id);
+ return buildNewViews(id, objectp);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryObject const* objectp)
+{
+ if (!objectp)
+ {
+ return NULL;
+ }
+ if (!typedViewsFilter(id, objectp))
{
+ // if certain types are not allowed permanently, no reason to create views
return NULL;
}
- LLFolderViewItem* folder_view_item = getItemByID(id);
+ const LLUUID &parent_id = objectp->getParentUUID();
+ LLFolderViewItem* folder_view_item = getItemByID(id);
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+ return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *folder_view_item)
+{
+ if (!objectp)
+ {
+ return NULL;
+ }
+ if (!typedViewsFilter(id, objectp))
+ {
+ // if certain types are not allowed permanently, no reason to create views
+ return NULL;
+ }
const LLUUID &parent_id = objectp->getParentUUID();
- LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
-
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+ return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
+ const LLUUID& parent_id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *folder_view_item,
+ LLFolderViewFolder *parent_folder)
+{
// Force the creation of an extra root level folder item if required by the inventory panel (default is "false")
bool allow_drop = true;
bool create_root = false;
@@ -863,7 +957,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
if (objectp->getType() <= LLAssetType::AT_NONE)
{
- LL_WARNS() << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+ LL_WARNS() << "LLInventoryPanel::buildViewsTree called with invalid objectp->mType : "
<< ((S32)objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
return NULL;
@@ -872,7 +966,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
if (objectp->getType() >= LLAssetType::AT_COUNT)
{
// Example: Happens when we add assets of new, not yet supported type to library
- LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
+ LL_DEBUGS() << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
@@ -949,26 +1043,52 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
mInventory->lockDirectDescendentArrays(id, categories, items);
-
+
+ LLFolderViewFolder *parentp = dynamic_cast<LLFolderViewFolder*>(folder_view_item);
+
if(categories)
- {
+ {
+ bool has_folders = parentp->getFoldersCount() > 0;
for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
cat_iter != categories->end();
++cat_iter)
{
const LLViewerInventoryCategory* cat = (*cat_iter);
- buildNewViews(cat->getUUID());
+ if (typedViewsFilter(cat->getUUID(), cat))
+ {
+ if (has_folders)
+ {
+ // This can be optimized: we don't need to call getItemByID()
+ // each time, especially since content is growing, we can just
+ // iter over copy of mItemMap in some way
+ LLFolderViewItem* view_itemp = getItemByID(cat->getUUID());
+ buildViewsTree(cat->getUUID(), id, cat, view_itemp, parentp);
+ }
+ else
+ {
+ buildViewsTree(cat->getUUID(), id, cat, NULL, parentp);
+ }
+ }
}
}
if(items)
- {
+ {
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
++item_iter)
{
const LLViewerInventoryItem* item = (*item_iter);
- buildNewViews(item->getUUID());
+ if (typedViewsFilter(item->getUUID(), item))
+ {
+
+ // This can be optimized: we don't need to call getItemByID()
+ // each time, especially since content is growing, we can just
+ // iter over copy of mItemMap in some way
+ LLFolderViewItem* view_itemp = getItemByID(item->getUUID());
+ buildViewsTree(item->getUUID(), id, item, view_itemp, parentp);
+ }
+
}
}
mInventory->unlockDirectDescendentArrays(id);
@@ -1121,6 +1241,12 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
void LLInventoryPanel::clearSelection()
{
mSelectThisID.setNull();
+ mFocusSelection = false;
+}
+
+LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const
+{
+ return mFolderRoot.get()->getSelectionList();
}
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -1590,15 +1716,17 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus )
{
LLFolderViewItem* itemp = getItemByID(obj_id);
- if(itemp && itemp->getViewModelItem())
+ if(itemp && itemp->getViewModelItem() && itemp->passedFilter())
{
itemp->arrangeAndSet(TRUE, take_keyboard_focus);
mSelectThisID.setNull();
+ mFocusSelection = false;
return;
}
else
{
// save the desired item to be selected later (if/when ready)
+ mFocusSelection = take_keyboard_focus;
mSelectThisID = obj_id;
}
}
@@ -1607,7 +1735,7 @@ void LLInventoryPanel::updateSelection()
{
if (mSelectThisID.notNull())
{
- setSelectionByID(mSelectThisID, false);
+ setSelectionByID(mSelectThisID, mFocusSelection);
}
}
@@ -1632,21 +1760,18 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
// Open selected items if enter key hit on the inventory panel
if (mask == MASK_NONE)
{
-
-// @TODO$: Rider: This code is dead with Outbox, however should something similar be
-// done for VMM?
-//
-// //Don't allow attaching or opening items from Merchant Outbox
-// LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();
-// if(folder_item)
-// {
-// LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
-// if(bridge && bridge->is() && (bridge->getInventoryType() != LLInventoryType::IT_CATEGORY))
-// {
-// return handled;
-// }
-// }
-
+ if (mSuppressOpenItemAction)
+ {
+ LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();
+ if(folder_item)
+ {
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+ if(bridge && (bridge->getInventoryType() != LLInventoryType::IT_CATEGORY))
+ {
+ return handled;
+ }
+ }
+ }
LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "open");
handled = TRUE;
}
@@ -1699,9 +1824,6 @@ bool LLInventoryPanel::isSelectionRemovable()
/************************************************************************/
/* Recent Inventory Panel related class */
/************************************************************************/
-class LLInventoryRecentItemsPanel;
-static LLDefaultChildRegistry::Register<LLInventoryRecentItemsPanel> t_recent_inventory_panel("recent_inventory_panel");
-
static const LLRecentInventoryBridgeBuilder RECENT_ITEMS_BUILDER;
class LLInventoryRecentItemsPanel : public LLInventoryPanel
{
@@ -1730,6 +1852,76 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
}
+/************************************************************************/
+/* Asset Pre-Filtered Inventory Panel related class */
+/************************************************************************/
+
+void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
+{
+ mAssetType = LLAssetType::lookup(p.filter_asset_type.getValue());
+ LLInventoryPanel::initFromParams(p);
+ U64 filter_cats = getFilter().getFilterCategoryTypes();
+ filter_cats &= ~(1ULL << LLFolderType::FT_MARKETPLACE_LISTINGS);
+ getFilter().setFilterCategoryTypes(filter_cats);
+ getFilter().setFilterNoMarketplaceFolder();
+}
+
+BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL result = FALSE;
+
+ 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)
+ {
+ result = LLInventoryPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+ }
+
+ return result;
+}
+
+/*virtual*/
+bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp)
+{
+ if (!objectp)
+ {
+ return false;
+ }
+
+ if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item)
+{
+ if (!model_item && !getItemByID(id))
+ {
+ // remove operation, but item is not in panel already
+ return;
+ }
+
+ if (model_item
+ && model_item->getType() != mAssetType
+ && model_item->getType() != LLAssetType::AT_CATEGORY)
+ {
+ return;
+ }
+
+ LLInventoryPanel::itemChanged(id, mask, model_item);
+}
+
namespace LLInitParam
{
void TypeValues<LLFolderType::EType>::declareValues()
@@ -1759,6 +1951,7 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_INBOX) , LLFolderType::FT_INBOX);
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_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 12001f5a2b..a019fc2231 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -92,11 +92,13 @@ public:
Optional<std::string> sort_order_setting;
Optional<LLInventoryModel*> inventory;
Optional<bool> allow_multi_select;
+ Optional<bool> allow_drag;
Optional<bool> show_item_link_overlays;
Optional<Filter> filter;
Optional<StartFolder> start_folder;
Optional<bool> use_label_suffix;
Optional<bool> show_empty_message;
+ Optional<bool> suppress_folder_menu;
Optional<bool> show_root_folder;
Optional<bool> allow_drop_on_root;
Optional<bool> use_marketplace_folders;
@@ -106,11 +108,17 @@ public:
Optional<LLFolderViewFolder::Params> folder;
Optional<LLFolderViewItem::Params> item;
+ // All item and folder views will be initialized on init if true (default)
+ // Will initialize on visibility change otherwise.
+ Optional<bool> preinitialize_views;
+
Params()
: sort_order_setting("sort_order_setting"),
inventory("", &gInventory),
allow_multi_select("allow_multi_select", true),
+ allow_drag("allow_drag", true),
show_item_link_overlays("show_item_link_overlays", false),
+ suppress_folder_menu("suppress_folder_menu", false),
filter("filter"),
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
@@ -122,7 +130,8 @@ public:
accepts_drag_and_drop("accepts_drag_and_drop"),
folder_view("folder_view"),
folder("folder"),
- item("item")
+ item("item"),
+ preinitialize_views("preinitialize_views", true)
{}
};
@@ -144,14 +153,17 @@ public:
virtual ~LLInventoryPanel();
public:
+ typedef std::set<LLFolderViewItem*> selected_items_t;
+
LLInventoryModel* getModel() { return mInventory; }
LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
// LLView methods
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
void draw();
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
BOOL handleHover(S32 x, S32 y, MASK mask);
- BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
@@ -168,6 +180,8 @@ public:
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
void clearSelection();
+ selected_items_t getSelectedItems() const;
+
bool isSelectionRemovable();
LLInventoryFilter& getFilter();
const LLInventoryFilter& getFilter() const;
@@ -176,8 +190,9 @@ public:
U32 getFilterObjectTypes() const;
void setFilterPermMask(PermissionMask filter_perm_mask);
U32 getFilterPermMask() const;
- void setFilterWearableTypes(U64 filter);
- void setFilterSubString(const std::string& string);
+ void setFilterWearableTypes(U64 filter);
+ void setFilterSettingsTypes(U64 filter);
+ void setFilterSubString(const std::string& string);
const std::string getFilterSubString();
void setSinceLogoff(BOOL sl);
void setHoursAgo(U32 hours);
@@ -236,6 +251,8 @@ public:
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
void updateSelection();
+ void setSuppressOpenItemAction(bool supress_open_item) { mSuppressOpenItemAction = supress_open_item; }
+
LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; }
const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; }
@@ -252,10 +269,14 @@ protected:
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
+ bool mFocusSelection;
bool mAcceptsDragAndDrop;
bool mAllowMultiSelect;
+ bool mAllowDrag;
bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons
bool mShowEmptyMessage;
+ bool mSuppressFolderMenu;
+ bool mSuppressOpenItemAction;
LLHandle<LLFolderView> mFolderRoot;
LLScrollContainer* mScroller;
@@ -299,7 +320,7 @@ public:
void addHideFolderType(LLFolderType::EType folder_type);
public:
- BOOL getIsViewsInitialized() const { return mViewsInitialized; }
+ bool getViewsInitialized() const { return mViewsInitialized == VIEWS_INITIALIZED; }
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
@@ -311,15 +332,77 @@ protected:
static LLUIColor sLibraryColor;
static LLUIColor sLinkColor;
- LLFolderViewItem* buildNewViews(const LLUUID& id);
+ LLFolderViewItem* buildNewViews(const LLUUID& id);
+ LLFolderViewItem* buildNewViews(const LLUUID& id,
+ LLInventoryObject const* objectp);
+ LLFolderViewItem* buildNewViews(const LLUUID& id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *target_view);
+ // if certain types are not allowed, no reason to create views
+ virtual bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; }
+
+ virtual void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
virtual LLFolderView * createFolderRoot(LLUUID root_id );
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
private:
- bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
- bool mViewsInitialized; // Views have been generated
+ // buildViewsTree does not include some checks and is meant
+ // for recursive use, use buildNewViews() for first call
+ LLFolderViewItem* buildViewsTree(const LLUUID& id,
+ const LLUUID& parent_id,
+ LLInventoryObject const* objectp,
+ LLFolderViewItem *target_view,
+ LLFolderViewFolder *parent_folder_view);
+
+ typedef enum e_views_initialization_state
+ {
+ VIEWS_UNINITIALIZED = 0,
+ VIEWS_INITIALIZING,
+ VIEWS_INITIALIZED,
+ } EViewsInitializationState;
+
+ bool mBuildViewsOnInit;
+ EViewsInitializationState mViewsInitialized; // Whether views have been generated
+};
+
+/************************************************************************/
+/* Asset Pre-Filtered Inventory Panel related class */
+/* Exchanges filter's flexibility for speed of generation and */
+/* improved performance */
+/************************************************************************/
+
+class LLAssetFilteredInventoryPanel : public LLInventoryPanel
+{
+public:
+ struct Params
+ : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+ {
+ Mandatory<std::string> filter_asset_type;
+
+ Params() : filter_asset_type("filter_asset_type") {}
+ };
+
+ void initFromParams(const Params& p);
+protected:
+ LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {}
+ friend class LLUICtrlFactory;
+public:
+ ~LLAssetFilteredInventoryPanel() {}
+
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg) override;
+
+protected:
+ /*virtual*/ bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) override;
+ /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
+
+private:
+ LLAssetType::EType mAssetType;
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 59e14e6cc0..79fafade2d 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -37,6 +37,7 @@
#include "llui.h"
#include "llagent.h"
#include "llagentcamera.h"
+#include "llviewercamera.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewerwindow.h"
@@ -48,12 +49,14 @@ static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide
static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn");
static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate");
static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track");
-
+static LLDefaultChildRegistry::Register<LLJoystickQuaternion> r6("joystick_quat");
const F32 NUDGE_TIME = 0.25f; // in seconds
const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
+const S32 CENTER_DOT_RADIUS = 7;
+
//
// Public Methods
//
@@ -138,9 +141,25 @@ bool LLJoystick::pointInCircle(S32 x, S32 y) const
//center is x and y coordinates of center of joystick circle, and also its radius
int center = this->getLocalRect().getHeight()/2;
bool in_circle = (x - center) * (x - center) + (y - center) * (y - center) <= center * center;
+
return in_circle;
}
+bool LLJoystick::pointInCenterDot(S32 x, S32 y, S32 radius) const
+{
+ if (this->getLocalRect().getHeight() != this->getLocalRect().getWidth())
+ {
+ LL_WARNS() << "Joystick shape is not square" << LL_ENDL;
+ return true;
+ }
+
+ S32 center = this->getLocalRect().getHeight() / 2;
+
+ bool in_center_circle = (x - center) * (x - center) + (y - center) * (y - center) <= radius * radius;
+
+ return in_center_circle;
+}
+
BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask)
{
//LL_INFOS() << "joystick mouse down " << x << ", " << y << LL_ENDL;
@@ -403,8 +422,11 @@ LLJoystickCameraRotate::LLJoystickCameraRotate(const LLJoystickCameraRotate::Par
mInLeft( FALSE ),
mInTop( FALSE ),
mInRight( FALSE ),
- mInBottom( FALSE )
-{ }
+ mInBottom( FALSE ),
+ mInCenter( FALSE )
+{
+ mCenterImageName = "Cam_Rotate_Center";
+}
void LLJoystickCameraRotate::updateSlop()
@@ -434,7 +456,16 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
S32 dx = x - horiz_center;
S32 dy = y - vert_center;
- if (dy > dx && dy > -dx)
+ if (pointInCenterDot(x, y, CENTER_DOT_RADIUS))
+ {
+ mInitialOffset.mX = 0;
+ mInitialOffset.mY = 0;
+ mInitialQuadrant = JQ_ORIGIN;
+ mInCenter = TRUE;
+
+ resetJoystickCamera();
+ }
+ else if (dy > dx && dy > -dx)
{
// top
mInitialOffset.mX = 0;
@@ -469,9 +500,20 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLJoystickCameraRotate::handleMouseUp(S32 x, S32 y, MASK mask)
{
gAgent.setMovementLocked(FALSE);
+ mInCenter = FALSE;
return LLJoystick::handleMouseUp(x, y, mask);
}
+BOOL LLJoystickCameraRotate::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (!pointInCenterDot(x, y, CENTER_DOT_RADIUS))
+ {
+ mInCenter = FALSE;
+ }
+
+ return LLJoystick::handleHover(x, y, mask);
+}
+
void LLJoystickCameraRotate::onHeldDown()
{
updateSlop();
@@ -504,6 +546,11 @@ void LLJoystickCameraRotate::onHeldDown()
}
}
+void LLJoystickCameraRotate::resetJoystickCamera()
+{
+ gAgentCamera.resetCameraOrbit();
+}
+
F32 LLJoystickCameraRotate::getOrbitRate()
{
F32 time = getElapsedHeldDownTime();
@@ -536,24 +583,31 @@ void LLJoystickCameraRotate::draw()
getImageUnselected()->draw( 0, 0 );
LLPointer<LLUIImage> image = getImageSelected();
- if( mInTop )
+ if (mInCenter)
{
- drawRotatedImage( getImageSelected(), 0 );
+ drawRotatedImage(LLUI::getUIImage(mCenterImageName), 0);
}
-
- if( mInRight )
+ else
{
- drawRotatedImage( getImageSelected(), 1 );
- }
+ if (mInTop)
+ {
+ drawRotatedImage(getImageSelected(), 0);
+ }
- if( mInBottom )
- {
- drawRotatedImage( getImageSelected(), 2 );
- }
+ if (mInRight)
+ {
+ drawRotatedImage(getImageSelected(), 1);
+ }
- if( mInLeft )
- {
- drawRotatedImage( getImageSelected(), 3 );
+ if (mInBottom)
+ {
+ drawRotatedImage(getImageSelected(), 2);
+ }
+
+ if (mInLeft)
+ {
+ drawRotatedImage(getImageSelected(), 3);
+ }
}
}
@@ -613,7 +667,9 @@ LLJoystickCameraTrack::Params::Params()
LLJoystickCameraTrack::LLJoystickCameraTrack(const LLJoystickCameraTrack::Params& p)
: LLJoystickCameraRotate(p)
-{}
+{
+ mCenterImageName = "Cam_Tracking_Center";
+}
void LLJoystickCameraTrack::onHeldDown()
@@ -646,3 +702,243 @@ void LLJoystickCameraTrack::onHeldDown()
gAgentCamera.setPanDownKey(getOrbitRate());
}
}
+
+void LLJoystickCameraTrack::resetJoystickCamera()
+{
+ gAgentCamera.resetCameraPan();
+}
+
+//-------------------------------------------------------------------------------
+// LLJoystickQuaternion
+//-------------------------------------------------------------------------------
+
+LLJoystickQuaternion::Params::Params()
+{
+}
+
+LLJoystickQuaternion::LLJoystickQuaternion(const LLJoystickQuaternion::Params &p):
+ LLJoystick(p),
+ mInLeft(false),
+ mInTop(false),
+ mInRight(false),
+ mInBottom(false),
+ mVectorZero(0.0f, 0.0f, 1.0f),
+ mRotation(),
+ mUpDnAxis(1.0f, 0.0f, 0.0f),
+ mLfRtAxis(0.0f, 0.0f, 1.0f),
+ mXAxisIndex(2), // left & right across the control
+ mYAxisIndex(0), // up & down across the control
+ mZAxisIndex(1) // tested for above and below
+{
+ for (int i = 0; i < 3; ++i)
+ {
+ mLfRtAxis.mV[i] = (mXAxisIndex == i) ? 1.0 : 0.0;
+ mUpDnAxis.mV[i] = (mYAxisIndex == i) ? 1.0 : 0.0;
+ }
+}
+
+void LLJoystickQuaternion::setToggleState(BOOL left, BOOL top, BOOL right, BOOL bottom)
+{
+ mInLeft = left;
+ mInTop = top;
+ mInRight = right;
+ mInBottom = bottom;
+}
+
+BOOL LLJoystickQuaternion::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ updateSlop();
+
+ // Set initial offset based on initial click location
+ S32 horiz_center = getRect().getWidth() / 2;
+ S32 vert_center = getRect().getHeight() / 2;
+
+ S32 dx = x - horiz_center;
+ S32 dy = y - vert_center;
+
+ if (dy > dx && dy > -dx)
+ {
+ // top
+ mInitialOffset.mX = 0;
+ mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2;
+ mInitialQuadrant = JQ_UP;
+ }
+ else if (dy > dx && dy <= -dx)
+ {
+ // left
+ mInitialOffset.mX = -(mHorizSlopNear + mHorizSlopFar) / 2;
+ mInitialOffset.mY = 0;
+ mInitialQuadrant = JQ_LEFT;
+ }
+ else if (dy <= dx && dy <= -dx)
+ {
+ // bottom
+ mInitialOffset.mX = 0;
+ mInitialOffset.mY = -(mVertSlopNear + mVertSlopFar) / 2;
+ mInitialQuadrant = JQ_DOWN;
+ }
+ else
+ {
+ // right
+ mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2;
+ mInitialOffset.mY = 0;
+ mInitialQuadrant = JQ_RIGHT;
+ }
+
+ return LLJoystick::handleMouseDown(x, y, mask);
+}
+
+BOOL LLJoystickQuaternion::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ return LLJoystick::handleMouseUp(x, y, mask);
+}
+
+void LLJoystickQuaternion::onHeldDown()
+{
+ LLVector3 axis;
+ updateSlop();
+
+ S32 dx = mLastMouse.mX - mFirstMouse.mX + mInitialOffset.mX;
+ S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY;
+
+ // left-right rotation
+ if (dx > mHorizSlopNear)
+ {
+ axis += mUpDnAxis;
+ }
+ else if (dx < -mHorizSlopNear)
+ {
+ axis -= mUpDnAxis;
+ }
+
+ // over/under rotation
+ if (dy > mVertSlopNear)
+ {
+ axis += mLfRtAxis;
+ }
+ else if (dy < -mVertSlopNear)
+ {
+ axis -= mLfRtAxis;
+ }
+
+ if (axis.isNull())
+ return;
+
+ axis.normalize();
+
+ LLQuaternion delta;
+ delta.setAngleAxis(0.0523599f, axis); // about 3deg
+
+ mRotation *= delta;
+ setValue(mRotation.getValue());
+ onCommit();
+}
+
+void LLJoystickQuaternion::draw()
+{
+ LLGLSUIDefault gls_ui;
+
+ getImageUnselected()->draw(0, 0);
+ LLPointer<LLUIImage> image = getImageSelected();
+
+ if (mInTop)
+ {
+ drawRotatedImage(getImageSelected(), 0);
+ }
+
+ if (mInRight)
+ {
+ drawRotatedImage(getImageSelected(), 1);
+ }
+
+ if (mInBottom)
+ {
+ drawRotatedImage(getImageSelected(), 2);
+ }
+
+ if (mInLeft)
+ {
+ drawRotatedImage(getImageSelected(), 3);
+ }
+
+ LLVector3 draw_point = mVectorZero * mRotation;
+ S32 halfwidth = getRect().getWidth() / 2;
+ S32 halfheight = getRect().getHeight() / 2;
+ draw_point.mV[mXAxisIndex] = (draw_point.mV[mXAxisIndex] + 1.0) * halfwidth;
+ draw_point.mV[mYAxisIndex] = (draw_point.mV[mYAxisIndex] + 1.0) * halfheight;
+
+ gl_circle_2d(draw_point.mV[mXAxisIndex], draw_point.mV[mYAxisIndex], 4, 8,
+ draw_point.mV[mZAxisIndex] >= 0.f);
+
+}
+
+F32 LLJoystickQuaternion::getOrbitRate()
+{
+ return 1;
+}
+
+void LLJoystickQuaternion::updateSlop()
+{
+ // small fixed slop region
+ mVertSlopNear = 16;
+ mVertSlopFar = 32;
+
+ mHorizSlopNear = 16;
+ mHorizSlopFar = 32;
+}
+
+void LLJoystickQuaternion::drawRotatedImage(LLPointer<LLUIImage> image, S32 rotations)
+{
+ S32 width = image->getWidth();
+ S32 height = image->getHeight();
+ LLTexture* texture = image->getImage();
+
+ /*
+ * Scale texture coordinate system
+ * to handle the different between image size and size of texture.
+ */
+ F32 uv[][2] =
+ {
+ { (F32)width / texture->getWidth(), (F32)height / texture->getHeight() },
+ { 0.f, (F32)height / texture->getHeight() },
+ { 0.f, 0.f },
+ { (F32)width / texture->getWidth(), 0.f }
+ };
+
+ gGL.getTexUnit(0)->bind(texture);
+
+ gGL.color4fv(UI_VERTEX_COLOR.mV);
+
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.texCoord2fv(uv[(rotations + 0) % 4]);
+ gGL.vertex2i(width, height);
+
+ gGL.texCoord2fv(uv[(rotations + 1) % 4]);
+ gGL.vertex2i(0, height);
+
+ gGL.texCoord2fv(uv[(rotations + 2) % 4]);
+ gGL.vertex2i(0, 0);
+
+ gGL.texCoord2fv(uv[(rotations + 3) % 4]);
+ gGL.vertex2i(width, 0);
+ }
+ gGL.end();
+}
+
+void LLJoystickQuaternion::setRotation(const LLQuaternion &value)
+{
+ if (value != mRotation)
+ {
+ mRotation = value;
+ mRotation.normalize();
+ LLJoystick::setValue(mRotation.getValue());
+ }
+}
+
+LLQuaternion LLJoystickQuaternion::getRotation() const
+{
+ return mRotation;
+}
+
+
diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h
index 4e6c774cad..b7fdf63e58 100644
--- a/indra/newview/lljoystickbutton.h
+++ b/indra/newview/lljoystickbutton.h
@@ -30,6 +30,7 @@
#include "llbutton.h"
#include "llcoord.h"
#include "llviewertexture.h"
+#include "llquaternion.h"
typedef enum e_joystick_quadrant
{
@@ -79,7 +80,8 @@ public:
* Image containing circle is square and this square has adherent points with joystick
* circle. Make sure to change method according to shape other than square.
*/
- bool pointInCircle(S32 x, S32 y) const;
+ bool pointInCircle(S32 x, S32 y) const;
+ bool pointInCenterDot(S32 x, S32 y, S32 radius) const;
static std::string nameFromQuadrant(const EJoystickQuadrant quadrant);
static EJoystickQuadrant quadrantFromName(const std::string& name);
@@ -147,7 +149,9 @@ public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual void onHeldDown();
+ virtual void resetJoystickCamera();
virtual void draw();
protected:
@@ -160,6 +164,9 @@ protected:
BOOL mInTop;
BOOL mInRight;
BOOL mInBottom;
+ BOOL mInCenter;
+
+ std::string mCenterImageName;
};
@@ -176,6 +183,50 @@ public:
LLJoystickCameraTrack(const LLJoystickCameraTrack::Params&);
virtual void onHeldDown();
+ virtual void resetJoystickCamera();
+};
+
+//
+class LLJoystickQuaternion :
+ public LLJoystick
+{
+public:
+ struct Params :
+ public LLInitParam::Block<Params, LLJoystick::Params>
+ {
+ Params();
+ };
+
+ LLJoystickQuaternion(const LLJoystickQuaternion::Params &);
+
+ virtual void setToggleState(BOOL left, BOOL top, BOOL right, BOOL bottom);
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ virtual void onHeldDown();
+ virtual void draw();
+
+ void setRotation(const LLQuaternion &value);
+ LLQuaternion getRotation() const;
+
+protected:
+ F32 getOrbitRate();
+ virtual void updateSlop();
+ void drawRotatedImage(LLPointer<LLUIImage> image, S32 rotations);
+
+ BOOL mInLeft;
+ BOOL mInTop;
+ BOOL mInRight;
+ BOOL mInBottom;
+
+ S32 mXAxisIndex;
+ S32 mYAxisIndex;
+ S32 mZAxisIndex;
+
+ LLVector3 mVectorZero;
+ LLQuaternion mRotation;
+ LLVector3 mUpDnAxis;
+ LLVector3 mLfRtAxis;
};
#endif // LL_LLJOYSTICKBUTTON_H
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
new file mode 100644
index 0000000000..b6107eeedf
--- /dev/null
+++ b/indra/newview/llkeyconflict.cpp
@@ -0,0 +1,1015 @@
+/**
+ * @file llkeyconflict.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+/*
+ * App-wide preferences. Note that these are not per-user,
+ * because we need to load many preferences before we have
+ * a login name.
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llkeyconflict.h"
+
+#include "llinitparam.h"
+#include "llkeyboard.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewerinput.h"
+#include "llviewermenu.h"
+#include "llxuiparser.h"
+
+static const std::string saved_settings_key_controls[] = { "placeholder" }; // add settings from gSavedSettings here
+
+static const std::string filename_default = "key_bindings.xml";
+static const std::string filename_temporary = "key_bindings_tmp.xml"; // used to apply uncommited changes on the go.
+
+// LLKeyboard::stringFromMask is meant for UI and is OS dependent,
+// so this class uses it's own version
+std::string string_from_mask(MASK mask)
+{
+ std::string res;
+ if ((mask & MASK_CONTROL) != 0)
+ {
+ res = "CTL";
+ }
+ if ((mask & MASK_ALT) != 0)
+ {
+ if (!res.empty()) res += "_";
+ res += "ALT";
+ }
+ if ((mask & MASK_SHIFT) != 0)
+ {
+ if (!res.empty()) res += "_";
+ res += "SHIFT";
+ }
+
+ if (mask == MASK_NONE)
+ {
+ res = "NONE";
+ }
+ return res;
+}
+
+std::string string_from_mouse(EMouseClickType click, bool translate)
+{
+ std::string res;
+ switch (click)
+ {
+ case CLICK_LEFT:
+ res = "LMB";
+ break;
+ case CLICK_MIDDLE:
+ res = "MMB";
+ break;
+ case CLICK_RIGHT:
+ res = "RMB";
+ break;
+ case CLICK_BUTTON4:
+ res = "MB4";
+ break;
+ case CLICK_BUTTON5:
+ res = "MB5";
+ break;
+ case CLICK_DOUBLELEFT:
+ res = "Double LMB";
+ break;
+ default:
+ break;
+ }
+
+ if (translate && !res.empty())
+ {
+ res = LLTrans::getString(res);
+ }
+ return res;
+}
+
+// LLKeyConflictHandler
+
+S32 LLKeyConflictHandler::sTemporaryFileUseCount = 0;
+
+LLKeyConflictHandler::LLKeyConflictHandler()
+: mHasUnsavedChanges(false),
+ mUsesTemporaryFile(false),
+ mLoadMode(MODE_COUNT)
+{
+}
+
+LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode)
+: mHasUnsavedChanges(false),
+ mUsesTemporaryFile(false),
+ mLoadMode(mode)
+{
+ loadFromSettings(mode);
+}
+
+LLKeyConflictHandler::~LLKeyConflictHandler()
+{
+ clearUnsavedChanges();
+ // Note: does not reset bindings if temporary file was used
+}
+
+bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask)
+{
+ return mControlsMap[control_name].canHandle(mouse_ind, key, mask);
+}
+
+bool LLKeyConflictHandler::canHandleKey(const std::string &control_name, KEY key, MASK mask)
+{
+ return canHandleControl(control_name, CLICK_NONE, key, mask);
+}
+
+bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask)
+{
+ return canHandleControl(control_name, mouse_ind, KEY_NONE, mask);
+}
+
+bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask)
+{
+ return canHandleControl(control_name, (EMouseClickType)mouse_ind, KEY_NONE, mask);
+}
+
+bool LLKeyConflictHandler::canAssignControl(const std::string &control_name)
+{
+ control_map_t::iterator iter = mControlsMap.find(control_name);
+ if (iter != mControlsMap.end())
+ {
+ return iter->second.mAssignable;
+ }
+ // If we don't know this control, means it wasn't assigned by user yet and thus is editable
+ return true;
+}
+
+// static
+bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask)
+{
+ if (key == KEY_NONE)
+ {
+ return false;
+ }
+ return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask))
+ || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask));
+}
+
+// static
+bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data)
+{
+ if (data.mMouse != CLICK_NONE || data.mKey == KEY_NONE)
+ {
+ return false;
+ }
+ return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask))
+ || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask));
+}
+
+bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)
+{
+ if (control_name.empty())
+ {
+ return false;
+ }
+ LLKeyConflict &type_data = mControlsMap[control_name];
+ if (!type_data.mAssignable)
+ {
+ // Example: user tried to assign camera spin to all modes, but first person mode doesn't support it
+ return false;
+ }
+ LLKeyData data(mouse, key, mask, ignore_mask);
+ if (type_data.mKeyBind.getKeyData(index) == data)
+ {
+ return true;
+ }
+ if (isReservedByMenu(data))
+ {
+ return false;
+ }
+ if (removeConflicts(data, type_data.mConflictMask))
+ {
+ type_data.mKeyBind.replaceKeyData(data, index);
+ mHasUnsavedChanges = true;
+ return true;
+ }
+ // control already in use/blocked
+ return false;
+}
+
+bool LLKeyConflictHandler::clearControl(const std::string &control_name, U32 data_index)
+{
+ if (control_name.empty())
+ {
+ return false;
+ }
+ LLKeyConflict &type_data = mControlsMap[control_name];
+ if (!type_data.mAssignable)
+ {
+ // Example: user tried to assign camera spin to all modes, but first person mode doesn't support it
+ return false;
+ }
+ type_data.mKeyBind.resetKeyData(data_index);
+ mHasUnsavedChanges = true;
+ return true;
+}
+
+LLKeyData LLKeyConflictHandler::getControl(const std::string &control_name, U32 index)
+{
+ if (control_name.empty())
+ {
+ return LLKeyData();
+ }
+ return mControlsMap[control_name].getKeyData(index);
+}
+
+bool LLKeyConflictHandler::isControlEmpty(const std::string &control_name)
+{
+ if (control_name.empty())
+ {
+ return true;
+ }
+ return mControlsMap[control_name].mKeyBind.isEmpty();
+}
+
+// static
+std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata)
+{
+ std::string result;
+
+ if (keydata.mMask != MASK_NONE && keydata.mKey != KEY_NONE)
+ {
+ result = LLKeyboard::stringFromAccelerator(keydata.mMask, keydata.mKey);
+ }
+ else if (keydata.mKey != KEY_NONE)
+ {
+ result = LLKeyboard::stringFromKey(keydata.mKey);
+ }
+ else if (keydata.mMask != MASK_NONE)
+ {
+ result = LLKeyboard::stringFromAccelerator(keydata.mMask);
+ }
+
+ result += string_from_mouse(keydata.mMouse, true);
+
+ return result;
+}
+
+std::string LLKeyConflictHandler::getControlString(const std::string &control_name, U32 index)
+{
+ if (control_name.empty())
+ {
+ return "";
+ }
+ return getStringFromKeyData(mControlsMap[control_name].getKeyData(index));
+}
+
+void LLKeyConflictHandler::loadFromControlSettings(const std::string &name)
+{
+ LLControlVariablePtr var = gSavedSettings.getControl(name);
+ if (var)
+ {
+ LLKeyBind bind(var->getValue());
+ LLKeyConflict key(bind, true, 0);
+ mControlsMap[name] = key;
+ }
+}
+
+void LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination)
+{
+ for (LLInitParam::ParamIterator<LLViewerInput::KeyBinding>::const_iterator it = keymode.bindings.begin(),
+ end_it = keymode.bindings.end();
+ it != end_it;
+ ++it)
+ {
+ KEY key;
+ MASK mask;
+ EMouseClickType mouse = CLICK_NONE;
+ if (it->mouse.isProvided())
+ {
+ LLViewerInput::mouseFromString(it->mouse.getValue(), &mouse);
+ }
+ if (it->key.getValue().empty())
+ {
+ key = KEY_NONE;
+ }
+ else
+ {
+ LLKeyboard::keyFromString(it->key, &key);
+ }
+ LLKeyboard::maskFromString(it->mask, &mask);
+ // Note: it->command is also the name of UI element, howhever xml we are loading from
+ // might not know all the commands, so UI will have to know what to fill by its own
+ // Assumes U32_MAX conflict mask, and is assignable by default,
+ // but assignability might have been overriden by generatePlaceholders.
+ LLKeyConflict &type_data = (*destination)[it->command];
+ type_data.mKeyBind.addKeyData(mouse, key, mask, true);
+ }
+}
+
+bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination)
+{
+ if (filename.empty())
+ {
+ return false;
+ }
+
+ bool res = false;
+
+ LLViewerInput::Keys keys;
+ LLSimpleXUIParser parser;
+
+ if (parser.readXUI(filename, keys)
+ && keys.validateBlock())
+ {
+ switch (load_mode)
+ {
+ case MODE_FIRST_PERSON:
+ if (keys.first_person.isProvided())
+ {
+ loadFromSettings(keys.first_person, destination);
+ res = true;
+ }
+ break;
+ case MODE_THIRD_PERSON:
+ if (keys.third_person.isProvided())
+ {
+ loadFromSettings(keys.third_person, destination);
+ res = true;
+ }
+ break;
+ case MODE_EDIT_AVATAR:
+ if (keys.edit_avatar.isProvided())
+ {
+ loadFromSettings(keys.edit_avatar, destination);
+ res = true;
+ }
+ break;
+ case MODE_SITTING:
+ if (keys.sitting.isProvided())
+ {
+ loadFromSettings(keys.sitting, destination);
+ res = true;
+ }
+ break;
+ default:
+ LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL;
+ break;
+ }
+ }
+ return res;
+}
+
+void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
+{
+ mControlsMap.clear();
+ mDefaultsMap.clear();
+
+ // E.X. In case we need placeholder keys for conflict resolution.
+ generatePlaceholders(load_mode);
+
+ if (load_mode == MODE_SAVED_SETTINGS)
+ {
+ // load settings clss knows about, but it also possible to load settings by name separately
+ const S32 size = std::extent<decltype(saved_settings_key_controls)>::value;
+ for (U32 i = 0; i < size; i++)
+ {
+ loadFromControlSettings(saved_settings_key_controls[i]);
+ }
+ }
+ else
+ {
+ // load defaults
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
+ if (!loadFromSettings(load_mode, filename, &mDefaultsMap))
+ {
+ LL_WARNS() << "Failed to load default settings, aborting" << LL_ENDL;
+ return;
+ }
+
+ // load user's
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+ if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap))
+ {
+ // mind placeholders
+ mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+ }
+ }
+ mLoadMode = load_mode;
+}
+
+void LLKeyConflictHandler::saveToSettings(bool temporary)
+{
+ if (mControlsMap.empty())
+ {
+ return;
+ }
+
+ if (mLoadMode == MODE_SAVED_SETTINGS)
+ {
+ // Does not support 'temporary', preferences handle that themself
+ // so in case of saved settings we just do not clear mHasUnsavedChanges
+ control_map_t::iterator iter = mControlsMap.begin();
+ control_map_t::iterator end = mControlsMap.end();
+
+ for (; iter != end; ++iter)
+ {
+ if (iter->first.empty())
+ {
+ continue;
+ }
+
+ LLKeyConflict &key = iter->second;
+ key.mKeyBind.trimEmpty();
+ if (!key.mAssignable)
+ {
+ continue;
+ }
+
+ if (gSavedSettings.controlExists(iter->first))
+ {
+ gSavedSettings.setLLSD(iter->first, key.mKeyBind.asLLSD());
+ }
+ else if (!key.mKeyBind.empty())
+ {
+ // Note: this is currently not in use, might be better for load mechanics to ask for and retain control group
+ // otherwise settings loaded from other control groups will end in gSavedSettings
+ LL_INFOS() << "Creating new keybinding " << iter->first << LL_ENDL;
+ gSavedSettings.declareLLSD(iter->first, key.mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS);
+ }
+ }
+ }
+ else
+ {
+ // Determine what file to load and load full copy of that file
+ std::string filename;
+
+ if (temporary)
+ {
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+ if (!gDirUtilp->fileExists(filename))
+ {
+ filename.clear();
+ }
+ }
+
+ if (filename.empty())
+ {
+ filename = gDirUtilp->findFile(filename_default,
+ gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
+ gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+ }
+
+ LLViewerInput::Keys keys;
+ LLSimpleXUIParser parser;
+
+ if (parser.readXUI(filename, keys)
+ && keys.validateBlock())
+ {
+ // replace category we edited
+
+ // mode is a HACK to correctly reset bindings without reparsing whole file and avoid doing
+ // own param container (which will face issues with inasseesible members of LLInitParam)
+ LLViewerInput::KeyMode mode;
+ LLViewerInput::KeyBinding binding;
+
+ control_map_t::iterator iter = mControlsMap.begin();
+ control_map_t::iterator end = mControlsMap.end();
+ for (; iter != end; ++iter)
+ {
+ // By default xml have (had) up to 6 elements per function
+ // eventually it will be cleaned up and UI will only shows 3 per function,
+ // so make sure to cleanup.
+ // Also this helps in keeping file small.
+ iter->second.mKeyBind.trimEmpty();
+ U32 size = iter->second.mKeyBind.getDataCount();
+ for (U32 i = 0; i < size; ++i)
+ {
+ if (iter->first.empty())
+ {
+ continue;
+ }
+
+ LLKeyConflict &key = iter->second;
+ key.mKeyBind.trimEmpty();
+ if (key.mKeyBind.empty() || !key.mAssignable)
+ {
+ continue;
+ }
+
+ LLKeyData data = key.mKeyBind.getKeyData(i);
+ // Still write empty LLKeyData to make sure we will maintain UI position
+ if (data.mKey == KEY_NONE)
+ {
+ // Might be better idea to be consistent and use NONE. LLViewerInput can work with both cases
+ binding.key = "";
+ }
+ else
+ {
+ binding.key = LLKeyboard::stringFromKey(data.mKey, false /*Do not localize*/);
+ }
+ binding.mask = string_from_mask(data.mMask);
+ if (data.mMouse == CLICK_NONE)
+ {
+ binding.mouse.setProvided(false);
+ }
+ else
+ {
+ // set() because 'optional', for compatibility purposes
+ // just copy old keys.xml and rename to key_bindings.xml, it should work
+ binding.mouse.set(string_from_mouse(data.mMouse, false), true);
+ }
+ binding.command = iter->first;
+ mode.bindings.add(binding);
+ }
+ }
+
+ switch (mLoadMode)
+ {
+ case MODE_FIRST_PERSON:
+ if (keys.first_person.isProvided())
+ {
+ keys.first_person.bindings.set(mode.bindings, true);
+ }
+ break;
+ case MODE_THIRD_PERSON:
+ if (keys.third_person.isProvided())
+ {
+ keys.third_person.bindings.set(mode.bindings, true);
+ }
+ break;
+ case MODE_EDIT_AVATAR:
+ if (keys.edit_avatar.isProvided())
+ {
+ keys.edit_avatar.bindings.set(mode.bindings, true);
+ }
+ break;
+ case MODE_SITTING:
+ if (keys.sitting.isProvided())
+ {
+ keys.sitting.bindings.set(mode.bindings, true);
+ }
+ break;
+ default:
+ LL_ERRS() << "Not implememted mode " << mLoadMode << LL_ENDL;
+ break;
+ }
+
+ if (temporary)
+ {
+ // write to temporary xml and use it for gViewerInput
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+ if (!mUsesTemporaryFile)
+ {
+ mUsesTemporaryFile = true;
+ sTemporaryFileUseCount++;
+ }
+ }
+ else
+ {
+ // write back to user's xml and use it for gViewerInput
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+ // Don't reset mUsesTemporaryFile, it will be reset at cleanup stage
+ }
+
+ LLXMLNodePtr output_node = new LLXMLNode("keys", false);
+ LLXUIParser parser;
+ parser.writeXUI(output_node, keys);
+
+ // Write the resulting XML to file
+ if (!output_node->isNull())
+ {
+ LLFILE *fp = LLFile::fopen(filename, "w");
+ if (fp != NULL)
+ {
+ LLXMLNode::writeHeaderToFile(fp);
+ output_node->writeToFile(fp);
+ fclose(fp);
+ }
+ }
+ // Now force a rebind for keyboard
+ if (gDirUtilp->fileExists(filename))
+ {
+ // Ideally instead of rebinding immediately we should shedule
+ // the rebind since single file can have multiple handlers,
+ // one per mode, saving simultaneously.
+ // Or whatever uses LLKeyConflictHandler should control the process.
+ gViewerInput.loadBindingsXML(filename);
+ }
+ }
+ }
+
+#if 1
+ // Legacy support
+ // Remove #if-#endif section half a year after DRTVWR-501 releases.
+ // Update legacy settings in settings.xml
+ // We only care for third person view since legacy settings can't store
+ // more than one mode.
+ // We are saving this even if we are in temporary mode - preferences
+ // will restore values on cancel
+ if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges)
+ {
+ bool value = canHandleMouse("walk_to", CLICK_DOUBLELEFT, MASK_NONE);
+ gSavedSettings.setBOOL("DoubleClickAutoPilot", value);
+
+ value = canHandleMouse("walk_to", CLICK_LEFT, MASK_NONE);
+ gSavedSettings.setBOOL("ClickToWalk", value);
+
+ // new method can save both toggle and push-to-talk values simultaneously,
+ // but legacy one can save only one. It also doesn't support mask.
+ LLKeyData data = getControl("toggle_voice", 0);
+ bool can_toggle = !data.isEmpty();
+ if (!can_toggle)
+ {
+ data = getControl("voice_follow_key", 0);
+ }
+
+ gSavedSettings.setBOOL("PushToTalkToggle", can_toggle);
+ if (data.isEmpty())
+ {
+ // legacy viewer has a bug that might crash it if NONE value is assigned.
+ // just reset to default
+ gSavedSettings.getControl("PushToTalkButton")->resetToDefault(false);
+ }
+ else
+ {
+ if (data.mKey != KEY_NONE)
+ {
+ gSavedSettings.setString("PushToTalkButton", LLKeyboard::stringFromKey(data.mKey));
+ }
+ else
+ {
+ std::string ctrl_value;
+ switch (data.mMouse)
+ {
+ case CLICK_MIDDLE:
+ ctrl_value = "MiddleMouse";
+ break;
+ case CLICK_BUTTON4:
+ ctrl_value = "MouseButton4";
+ break;
+ case CLICK_BUTTON5:
+ ctrl_value = "MouseButton5";
+ break;
+ default:
+ ctrl_value = "MiddleMouse";
+ break;
+ }
+ gSavedSettings.setString("PushToTalkButton", ctrl_value);
+ }
+ }
+ }
+#endif
+
+ if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges)
+ {
+ // Map floater should react to doubleclick if doubleclick for teleport is set
+ // Todo: Seems conterintuitive for map floater to share inworld controls
+ // after these changes release, discuss with UI UX engineer if this should just
+ // be set to 1 by default (before release this also doubles as legacy support)
+ bool value = canHandleMouse("teleport_to", CLICK_DOUBLELEFT, MASK_NONE);
+ gSavedSettings.setBOOL("DoubleClickTeleport", value);
+ }
+
+ if (!temporary)
+ {
+ // will remove any temporary file if there were any
+ clearUnsavedChanges();
+ }
+}
+
+LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index)
+{
+ if (control_name.empty())
+ {
+ return LLKeyData();
+ }
+ if (mLoadMode == MODE_SAVED_SETTINGS)
+ {
+ LLControlVariablePtr var = gSavedSettings.getControl(control_name);
+ if (var)
+ {
+ return LLKeyBind(var->getDefault()).getKeyData(index);
+ }
+ return LLKeyData();
+ }
+ else
+ {
+ control_map_t::iterator iter = mDefaultsMap.find(control_name);
+ if (iter != mDefaultsMap.end())
+ {
+ return iter->second.mKeyBind.getKeyData(index);
+ }
+ return LLKeyData();
+ }
+}
+
+void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 index)
+{
+ if (control_name.empty())
+ {
+ return;
+ }
+ LLKeyData data = getDefaultControl(control_name, index);
+
+ if (data != mControlsMap[control_name].getKeyData(index))
+ {
+ // reset controls that might have been switched to our current control
+ removeConflicts(data, mControlsMap[control_name].mConflictMask);
+ mControlsMap[control_name].setKeyData(data, index);
+ }
+}
+
+void LLKeyConflictHandler::resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts)
+{
+ if (control_name.empty())
+ {
+ return;
+ }
+ if (mLoadMode == MODE_SAVED_SETTINGS)
+ {
+ LLControlVariablePtr var = gSavedSettings.getControl(control_name);
+ if (var)
+ {
+ LLKeyBind bind(var->getDefault());
+ if (!ignore_conflicts)
+ {
+ for (S32 i = 0; i < bind.getDataCount(); ++i)
+ {
+ removeConflicts(bind.getKeyData(i), mControlsMap[control_name].mConflictMask);
+ }
+ }
+ mControlsMap[control_name].mKeyBind = bind;
+ }
+ else
+ {
+ mControlsMap[control_name].mKeyBind.clear();
+ }
+ }
+ else
+ {
+ control_map_t::iterator iter = mDefaultsMap.find(control_name);
+ if (iter != mDefaultsMap.end())
+ {
+ if (!ignore_conflicts)
+ {
+ for (S32 i = 0; i < iter->second.mKeyBind.getDataCount(); ++i)
+ {
+ removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_name].mConflictMask);
+ }
+ }
+ mControlsMap[control_name].mKeyBind = iter->second.mKeyBind;
+ }
+ else
+ {
+ mControlsMap[control_name].mKeyBind.clear();
+ }
+ }
+}
+
+void LLKeyConflictHandler::resetToDefault(const std::string &control_name)
+{
+ // reset specific binding without ignoring conflicts
+ resetToDefaultAndResolve(control_name, false);
+}
+
+void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
+{
+ if (mode == MODE_SAVED_SETTINGS)
+ {
+ control_map_t::iterator iter = mControlsMap.begin();
+ control_map_t::iterator end = mControlsMap.end();
+
+ for (; iter != end; ++iter)
+ {
+ resetToDefaultAndResolve(iter->first, true);
+ }
+ }
+ else
+ {
+ mControlsMap.clear();
+ generatePlaceholders(mode);
+ mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+ }
+
+ mHasUnsavedChanges = true;
+}
+
+void LLKeyConflictHandler::resetToDefaults()
+{
+ if (!empty())
+ {
+ resetToDefaults(mLoadMode);
+ }
+ else
+ {
+ // not optimal since:
+ // 1. We are not sure that mLoadMode was set
+ // 2. We are not sure if there are any changes in comparison to default
+ // 3. We are loading 'current' only to replace it
+ // but it is reliable and works Todo: consider optimizing.
+ loadFromSettings(mLoadMode);
+ resetToDefaults(mLoadMode);
+ }
+}
+
+void LLKeyConflictHandler::clear()
+{
+ if (clearUnsavedChanges())
+ {
+ // temporary file was removed, this means we were using it and need to reload keyboard's bindings
+ resetKeyboardBindings();
+ }
+ mControlsMap.clear();
+ mDefaultsMap.clear();
+}
+
+// static
+void LLKeyConflictHandler::resetKeyboardBindings()
+{
+ // Try to load User's bindings first
+ std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+ if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+ {
+ // Failed to load custom bindings, try default ones
+ key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
+ if (!gViewerInput.loadBindingsXML(key_bindings_file))
+ {
+ LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+ }
+ }
+}
+
+void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
+{
+ // These controls are meant to cause conflicts when user tries to assign same control somewhere else
+ // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks
+
+ if (load_mode == MODE_FIRST_PERSON)
+ {
+ // First person view doesn't support camera controls
+ // Note: might be better idea to just load these from control_table_contents_camera.xml
+ // or to pass from floaterpreferences when it loads said file
+ registerTemporaryControl("look_up");
+ registerTemporaryControl("look_down");
+ registerTemporaryControl("move_forward");
+ registerTemporaryControl("move_backward");
+ registerTemporaryControl("move_forward_fast");
+ registerTemporaryControl("move_backward_fast");
+ registerTemporaryControl("spin_over");
+ registerTemporaryControl("spin_under");
+ registerTemporaryControl("pan_up");
+ registerTemporaryControl("pan_down");
+ registerTemporaryControl("pan_left");
+ registerTemporaryControl("pan_right");
+ registerTemporaryControl("pan_in");
+ registerTemporaryControl("pan_out");
+ registerTemporaryControl("spin_around_ccw");
+ registerTemporaryControl("spin_around_cw");
+
+ // control_table_contents_editing.xml
+ registerTemporaryControl("edit_avatar_spin_ccw");
+ registerTemporaryControl("edit_avatar_spin_cw");
+ registerTemporaryControl("edit_avatar_spin_over");
+ registerTemporaryControl("edit_avatar_spin_under");
+ registerTemporaryControl("edit_avatar_move_forward");
+ registerTemporaryControl("edit_avatar_move_backward");
+
+ // no autopilot or teleport
+ registerTemporaryControl("walk_to");
+ registerTemporaryControl("teleport_to");
+ }
+
+ if (load_mode == MODE_EDIT_AVATAR)
+ {
+ // no autopilot or teleport
+ registerTemporaryControl("walk_to");
+ registerTemporaryControl("teleport_to");
+ }
+
+ if (load_mode == MODE_SITTING)
+ {
+ // no autopilot
+ registerTemporaryControl("walk_to");
+ }
+ else
+ {
+ // sitting related functions should only be avaliable in sitting mode
+ registerTemporaryControl("move_forward_sitting");
+ registerTemporaryControl("move_backward_sitting");
+ registerTemporaryControl("spin_over_sitting");
+ registerTemporaryControl("spin_under_sitting");
+ registerTemporaryControl("spin_around_ccw_sitting");
+ registerTemporaryControl("spin_around_cw_sitting");
+ }
+}
+
+bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask)
+{
+ if (conlict_mask == CONFLICT_NOTHING)
+ {
+ // Can't conflict
+ return true;
+ }
+ std::map<std::string, S32> conflict_list;
+ control_map_t::iterator cntrl_iter = mControlsMap.begin();
+ control_map_t::iterator cntrl_end = mControlsMap.end();
+ for (; cntrl_iter != cntrl_end; ++cntrl_iter)
+ {
+ S32 index = cntrl_iter->second.mKeyBind.findKeyData(data);
+ if (index >= 0
+ && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING
+ && (cntrl_iter->second.mConflictMask & conlict_mask) != 0)
+ {
+ if (cntrl_iter->second.mAssignable)
+ {
+ // Potentially we can have multiple conflict flags conflicting
+ // including unassignable keys.
+ // So record the conflict and find all others before doing any changes.
+ // Assume that there is only one conflict per bind
+ conflict_list[cntrl_iter->first] = index;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ std::map<std::string, S32>::iterator cnflct_iter = conflict_list.begin();
+ std::map<std::string, S32>::iterator cnflct_end = conflict_list.end();
+ for (; cnflct_iter != cnflct_end; ++cnflct_iter)
+ {
+ mControlsMap[cnflct_iter->first].mKeyBind.resetKeyData(cnflct_iter->second);
+ }
+ return true;
+}
+
+void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask)
+{
+ LLKeyConflict *type_data = &mControlsMap[control_name];
+ type_data->mAssignable = false;
+ type_data->mConflictMask = conflict_mask;
+ type_data->mKeyBind.addKeyData(mouse, key, mask, false);
+}
+
+void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, U32 conflict_mask)
+{
+ LLKeyConflict *type_data = &mControlsMap[control_name];
+ type_data->mAssignable = false;
+ type_data->mConflictMask = conflict_mask;
+}
+
+bool LLKeyConflictHandler::clearUnsavedChanges()
+{
+ bool result = false;
+ mHasUnsavedChanges = false;
+
+ if (mUsesTemporaryFile)
+ {
+ mUsesTemporaryFile = false;
+ sTemporaryFileUseCount--;
+ if (!sTemporaryFileUseCount)
+ {
+ result = clearTemporaryFile();
+ }
+ // else: might be usefull to overwrite content of temp file with defaults
+ // but at the moment there is no such need
+ }
+ return result;
+}
+
+//static
+bool LLKeyConflictHandler::clearTemporaryFile()
+{
+ // At the moment single file needs five handlers (one per mode), so doing this
+ // will remove file for all hadlers
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+ if (gDirUtilp->fileExists(filename))
+ {
+ LLFile::remove(filename);
+ return true;
+ }
+ return false;
+}
+
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
new file mode 100644
index 0000000000..2926ca3aeb
--- /dev/null
+++ b/indra/newview/llkeyconflict.h
@@ -0,0 +1,175 @@
+/**
+ * @file llkeyconflict.h
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#ifndef LL_LLKEYCONFLICT_H
+#define LL_LLKEYCONFLICT_H
+
+#include "llkeybind.h"
+#include "llviewerinput.h"
+
+
+class LLKeyConflict
+{
+public:
+ LLKeyConflict() : mAssignable(true), mConflictMask(U32_MAX) {} //temporary assignable, don't forget to change once all keys are recorded
+ LLKeyConflict(bool assignable, U32 conflict_mask)
+ : mAssignable(assignable), mConflictMask(conflict_mask) {}
+ LLKeyConflict(const LLKeyBind &bind, bool assignable, U32 conflict_mask)
+ : mAssignable(assignable), mConflictMask(conflict_mask), mKeyBind(bind) {}
+
+ LLKeyData getPrimaryKeyData() { return mKeyBind.getKeyData(0); }
+ LLKeyData getKeyData(U32 index) { return mKeyBind.getKeyData(index); }
+ void setPrimaryKeyData(const LLKeyData& data) { mKeyBind.replaceKeyData(data, 0); }
+ void setKeyData(const LLKeyData& data, U32 index) { mKeyBind.replaceKeyData(data, index); }
+ bool canHandle(EMouseClickType mouse, KEY key, MASK mask) { return mKeyBind.canHandle(mouse, key, mask); }
+
+ LLKeyBind mKeyBind;
+ bool mAssignable; // whether user can change key or key simply acts as placeholder
+ U32 mConflictMask;
+};
+
+class LLKeyConflictHandler
+{
+public:
+
+ enum ESourceMode // partially repeats e_keyboard_mode
+ {
+ MODE_FIRST_PERSON,
+ MODE_THIRD_PERSON,
+ MODE_EDIT_AVATAR,
+ MODE_SITTING,
+ MODE_SAVED_SETTINGS, // for settings from saved settings
+ MODE_COUNT
+ };
+
+ const U32 CONFLICT_NOTHING = 0;
+ // at the moment this just means that key will conflict with everything that is identical
+ const U32 CONFLICT_ANY = U32_MAX;
+
+ // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel)
+
+ LLKeyConflictHandler();
+ LLKeyConflictHandler(ESourceMode mode);
+ ~LLKeyConflictHandler();
+
+ bool canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask);
+ bool canHandleKey(const std::string &control_name, KEY key, MASK mask);
+ bool canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask);
+ bool canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask); //Just for convinience
+ bool canAssignControl(const std::string &control_name);
+ static bool isReservedByMenu(const KEY &key, const MASK &mask);
+ static bool isReservedByMenu(const LLKeyData &data);
+
+ // @control_name - see REGISTER_KEYBOARD_ACTION in llviewerinput for avaliable options,
+ // usually this is just name of the function
+ // @data_index - single control (function) can have multiple key combinations trigering
+ // it, this index indicates combination function will change/add; Note that preferences
+ // floater can only display up to 3 options, but data_index can be bigger than that
+ // @mouse_ind - mouse action (middle click, MB5 etc)
+ // @key - keyboard key action
+ // @mask - shift/ctrl/alt flags
+ // @ignore_mask - Either to expect exact match (ctrl+K will not trigger if ctrl+shift+K
+ // is active) or ignore not expected masks as long as expected mask is present
+ // (ctrl+K will be triggered if ctrl+shift+K is active)
+ bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts?
+ bool clearControl(const std::string &control_name, U32 data_index);
+
+ LLKeyData getControl(const std::string &control_name, U32 data_index);
+ bool isControlEmpty(const std::string &control_name);
+
+ // localized string
+ static std::string getStringFromKeyData(const LLKeyData& keydata);
+ std::string getControlString(const std::string &control_name, U32 data_index);
+
+ // Load single control, overrides existing one if names match
+ void loadFromControlSettings(const std::string &name);
+ // Drops any changes loads controls with ones from 'saved settings' or from xml
+ void loadFromSettings(ESourceMode load_mode);
+
+ // Saves settings to 'saved settings' or to xml
+ // If 'temporary' is set, function will save settings to temporary
+ // file and reload input bindings from temporary file.
+ // 'temporary' does not support gSavedSettings, those are handled
+ // by preferences, so 'temporary' is such case will simply not
+ // reset mHasUnsavedChanges
+ //
+ // 'temporary' exists to support ability of live-editing settings in
+ // preferences: temporary for testing changes 'live' without saving them,
+ // then hitting ok/cancel and save/discard values permanently.
+ void saveToSettings(bool apply_temporary = false);
+
+ LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);
+ // Resets keybinding to default variant from 'saved settings' or xml
+ void resetToDefault(const std::string &control_name, U32 index);
+ void resetToDefault(const std::string &control_name);
+ // resets current mode to defaults
+ void resetToDefaults();
+
+ bool empty() { return mControlsMap.empty(); }
+ void clear();
+
+ // reloads bindings from last valid user's xml or from default xml
+ // to keyboard's handler
+ static void resetKeyboardBindings();
+
+ bool hasUnsavedChanges() { return mHasUnsavedChanges; }
+ void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
+ ESourceMode getLoadMode() { return mLoadMode; }
+
+private:
+ void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts);
+ void resetToDefaults(ESourceMode mode);
+
+ // at the moment these kind of control is not savable, but takes part in conflict resolution
+ void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask);
+ void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);
+
+ typedef std::map<std::string, LLKeyConflict> control_map_t;
+ void loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination);
+ bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
+ void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
+ // returns false in case user is trying to reuse control that can't be reassigned
+ bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);
+
+ // removes flags and removes temporary file, returns 'true' if file was removed
+ bool clearUnsavedChanges();
+ // return true if there was a file to remove
+ static bool clearTemporaryFile();
+
+ control_map_t mControlsMap;
+ control_map_t mDefaultsMap;
+ bool mHasUnsavedChanges;
+ ESourceMode mLoadMode;
+
+ // To implement 'apply immediately'+revert on cancel, class applies changes to temporary file
+ // but this only works for settings from keybndings files (key_bindings.xml)
+ // saved setting rely onto external mechanism of preferences floater
+ bool mUsesTemporaryFile;
+ static S32 sTemporaryFileUseCount;
+};
+
+
+#endif // LL_LLKEYCONFLICT_H
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 9c00243f44..a17dc674ac 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -228,23 +228,6 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
}
-bool LLLandmarkActions::canCreateLandmarkHere()
-{
- LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(!agent_parcel)
- {
- LL_WARNS() << "No agent region" << LL_ENDL;
- return false;
- }
- if (agent_parcel->getAllowLandmark()
- || LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
- {
- return true;
- }
-
- return false;
-}
-
void LLLandmarkActions::createLandmarkHere(
const std::string& name,
const std::string& desc,
@@ -261,18 +244,13 @@ void LLLandmarkActions::createLandmarkHere(
LL_WARNS() << "No agent parcel" << LL_ENDL;
return;
}
- if (!canCreateLandmarkHere())
- {
- LLNotificationsUtil::add("CannotCreateLandmarkNotOwner");
- return;
- }
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, LLTransactionID::tnull,
name, desc,
LLAssetType::AT_LANDMARK,
LLInventoryType::IT_LANDMARK,
- NOT_WEARABLE, PERM_ALL,
+ NO_INV_SUBTYPE, PERM_ALL,
NULL);
}
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index 870d92811e..ae7b072fcb 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -72,12 +72,6 @@ public:
*/
static LLViewerInventoryItem* findLandmarkForAgentPos();
-
- /**
- * @brief Checks whether agent has rights to create landmark for current parcel.
- */
- static bool canCreateLandmarkHere();
-
/**
* @brief Creates landmark for current parcel.
*/
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index c58540914e..543d2a087f 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -39,6 +39,11 @@
// Globals
LLLandmarkList gLandmarkList;
+// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
+// which is 4096, to not overfill the pool if user has more than 4K of landmarks
+// and it should leave some space for other potential simultaneous asset request
+const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
+
////////////////////////////////////////////////////////////////////////////
// LLLandmarkList
@@ -69,6 +74,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
{
return NULL;
}
+ if ( mWaitList.find(asset_uuid) != mWaitList.end() )
+ {
+ // Landmark is sheduled for download, but not requested yet
+ return NULL;
+ }
landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid);
if (iter != mRequestedList.end())
@@ -86,11 +96,24 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
mLoadedCallbackMap.insert(vt);
}
+ if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
+ {
+ // Workarounds for corutines pending list size limit:
+ // Postpone download till queue is emptier.
+ // Coroutines have own built in 'pending' list, but unfortunately
+ // it is too small compared to potential amount of landmarks
+ // or assets.
+ mWaitList.insert(asset_uuid);
+ return NULL;
+ }
+
+ mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+ // Note that getAssetData can callback immediately and cleans mRequestedList
gAssetStorage->getAssetData(asset_uuid,
LLAssetType::AT_LANDMARK,
LLLandmarkList::processGetAssetReply,
NULL);
- mRequestedList[asset_uuid] = gFrameTimeSeconds;
}
return NULL;
}
@@ -155,8 +178,36 @@ void LLLandmarkList::processGetAssetReply(
}
gLandmarkList.mBadList.insert(uuid);
+ gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
+ // todo: this should clean mLoadedCallbackMap!
}
+ // getAssetData can fire callback immediately, causing
+ // a recursion which is suboptimal for very large wait list.
+ // 'scheduling' indicates that we are inside request and
+ // shouldn't be launching more requests.
+ static bool scheduling = false;
+ if (!scheduling && !gLandmarkList.mWaitList.empty())
+ {
+ scheduling = true;
+ while (!gLandmarkList.mWaitList.empty() && gLandmarkList.mRequestedList.size() < MAX_SIMULTANEOUS_REQUESTS)
+ {
+ // start new download from wait list
+ landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
+ LLUUID asset_uuid = *iter;
+ gLandmarkList.mWaitList.erase(iter);
+
+ // add to mRequestedList before calling getAssetData()
+ gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+ // Note that getAssetData can callback immediately and cleans mRequestedList
+ gAssetStorage->getAssetData(asset_uuid,
+ LLAssetType::AT_LANDMARK,
+ LLLandmarkList::processGetAssetReply,
+ NULL);
+ }
+ scheduling = false;
+ }
}
BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid)
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 3356f866ce..2e7bd25610 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -70,9 +70,10 @@ protected:
typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
landmark_list_t mList;
- typedef std::set<LLUUID> landmark_bad_list_t;
- landmark_bad_list_t mBadList;
-
+ typedef std::set<LLUUID> landmark_uuid_list_t;
+ landmark_uuid_list_t mBadList;
+ landmark_uuid_list_t mWaitList;
+
typedef std::map<LLUUID,F32> landmark_requested_list_t;
landmark_requested_list_t mRequestedList;
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
new file mode 100644
index 0000000000..a2acb3efe2
--- /dev/null
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -0,0 +1,853 @@
+/**
+ * @file lllegacyatmospherics.cpp
+ * @brief LLAtmospherics class implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lllegacyatmospherics.h"
+
+#include "llfeaturemanager.h"
+#include "llviewercontrol.h"
+#include "llframetimer.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "lldrawable.h"
+#include "llface.h"
+#include "llglheaders.h"
+#include "llsky.h"
+#include "llviewercamera.h"
+#include "llviewertexturelist.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "v3colorutil.h"
+
+#include "llsettingssky.h"
+#include "llenvironment.h"
+#include "lldrawpoolwater.h"
+
+class LLFastLn
+{
+public:
+ LLFastLn()
+ {
+ mTable[0] = 0;
+ for( S32 i = 1; i < 257; i++ )
+ {
+ mTable[i] = log((F32)i);
+ }
+ }
+
+ F32 ln( F32 x )
+ {
+ const F32 OO_255 = 0.003921568627450980392156862745098f;
+ const F32 LN_255 = 5.5412635451584261462455391880218f;
+
+ if( x < OO_255 )
+ {
+ return log(x);
+ }
+ else
+ if( x < 1 )
+ {
+ x *= 255.f;
+ S32 index = llfloor(x);
+ F32 t = x - index;
+ F32 low = mTable[index];
+ F32 high = mTable[index + 1];
+ return low + t * (high - low) - LN_255;
+ }
+ else
+ if( x <= 255 )
+ {
+ S32 index = llfloor(x);
+ F32 t = x - index;
+ F32 low = mTable[index];
+ F32 high = mTable[index + 1];
+ return low + t * (high - low);
+ }
+ else
+ {
+ return log( x );
+ }
+ }
+
+ F32 pow( F32 x, F32 y )
+ {
+ return (F32)LL_FAST_EXP(y * ln(x));
+ }
+
+
+private:
+ F32 mTable[257]; // index 0 is unused
+};
+
+static LLFastLn gFastLn;
+
+
+// Functions used a lot.
+
+inline F32 LLHaze::calcPhase(const F32 cos_theta) const
+{
+ const F32 g2 = mG * mG;
+ const F32 den = 1 + g2 - 2 * mG * cos_theta;
+ return (1 - g2) * gFastLn.pow(den, -1.5);
+}
+
+inline void color_pow(LLColor3 &col, const F32 e)
+{
+ col.mV[0] = gFastLn.pow(col.mV[0], e);
+ col.mV[1] = gFastLn.pow(col.mV[1], e);
+ col.mV[2] = gFastLn.pow(col.mV[2], e);
+}
+
+inline LLColor3 color_norm(const LLColor3 &col)
+{
+ const F32 m = color_max(col);
+ if (m > 1.f)
+ {
+ return 1.f/m * col;
+ }
+ else return col;
+}
+
+inline void color_gamma_correct(LLColor3 &col)
+{
+ const F32 gamma_inv = 1.f/1.2f;
+ if (col.mV[0] != 0.f)
+ {
+ col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv);
+ }
+ if (col.mV[1] != 0.f)
+ {
+ col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv);
+ }
+ if (col.mV[2] != 0.f)
+ {
+ col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv);
+ }
+}
+
+static LLColor3 calc_air_sca_sea_level()
+{
+ static LLColor3 WAVE_LEN(675, 520, 445);
+ static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN);
+ static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1);
+ static LLColor3 n4 = n21 * n21;
+ static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f;
+ static LLColor3 wl4 = wl2 * wl2;
+ static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4;
+ static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2);
+ return dens_div_N * mult_const.divide(wl4);
+}
+
+// static constants.
+LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level();
+F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);
+F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f;
+
+/***************************************
+ Atmospherics
+***************************************/
+
+LLAtmospherics::LLAtmospherics()
+: mCloudDensity(0.2f),
+ mWind(0.f),
+ mWorldScale(1.f)
+{
+ /// WL PARAMS
+ mInitialized = FALSE;
+ mAmbientScale = gSavedSettings.getF32("SkyAmbientScale");
+ mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift");
+ mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
+ mFogColor.mV[VALPHA] = 0.0f;
+ mFogRatio = 1.2f;
+ mHazeConcentration = 0.f;
+ mInterpVal = 0.f;
+}
+
+
+LLAtmospherics::~LLAtmospherics()
+{
+}
+
+void LLAtmospherics::init()
+{
+ const F32 haze_int = color_intens(mHaze.calcSigSca(0));
+ mHazeConcentration = haze_int / (color_intens(mHaze.calcAirSca(0)) + haze_int);
+ mInitialized = true;
+}
+
+LLColor4 LLAtmospherics::calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny)
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ return calcSkyColorInDir(psky, vars, dir, isShiny);
+}
+
+// This cubemap is used as "environmentMap" in indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+LLColor4 LLAtmospherics::calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3 &dir, bool isShiny)
+{
+ F32 sky_saturation = 0.25f;
+ F32 land_saturation = 0.1f;
+
+ if (isShiny && dir.mV[VZ] < -0.02f)
+ {
+ LLColor4 col;
+ LLColor3 desat_fog = LLColor3(mFogColor);
+ F32 brightness = desat_fog.brightness();// NOTE: Linear brightness!
+ // So that shiny somewhat shows up at night.
+ if (brightness < 0.15f)
+ {
+ brightness = 0.15f;
+ desat_fog = smear(0.15f);
+ }
+ F32 greyscale_sat = brightness * (1.0f - land_saturation);
+ desat_fog = desat_fog * land_saturation + smear(greyscale_sat);
+ if (!gPipeline.canUseWindLightShaders())
+ {
+ col = LLColor4(desat_fog, 0.f);
+ }
+ else
+ {
+ col = LLColor4(desat_fog * 0.5f, 0.f);
+ }
+ float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]);
+ x *= x;
+ col.mV[0] *= x*x;
+ col.mV[1] *= powf(x, 2.5f);
+ col.mV[2] *= x*x*x;
+ return col;
+ }
+
+ // undo OGL_TO_CFR_ROTATION and negate vertical direction.
+ LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
+
+ //calculates hazeColor
+ calcSkyColorWLVert(psky, Pn, vars);
+
+ if (isShiny)
+ {
+ F32 brightness = vars.hazeColor.brightness();
+ F32 greyscale_sat = brightness * (1.0f - sky_saturation);
+ LLColor3 sky_color = vars.hazeColor * sky_saturation + smear(greyscale_sat);
+ //sky_color *= (0.5f + 0.5f * brightness); // SL-12574 EEP sky is being attenuated too much
+ return LLColor4(sky_color, 0.0f);
+ }
+
+ bool low_end = !gPipeline.canUseWindLightShaders();
+ LLColor3 sky_color = low_end ? vars.hazeColor * 2.0f : psky->gammaCorrect(vars.hazeColor * 2.0f);
+
+ return LLColor4(sky_color, 0.0f);
+}
+
+// NOTE: Keep these in sync!
+// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
+// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+// indra\newview\lllegacyatmospherics.cpp
+void LLAtmospherics::calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars)
+{
+ LLColor3 blue_density = vars.blue_density;
+ LLColor3 blue_horizon = vars.blue_horizon;
+ F32 haze_horizon = vars.haze_horizon;
+ F32 haze_density = vars.haze_density;
+ F32 density_multiplier = vars.density_multiplier;
+ F32 max_y = vars.max_y;
+ LLVector4 sun_norm = vars.sun_norm;
+
+ // project the direction ray onto the sky dome.
+ F32 phi = acos(Pn[1]);
+ F32 sinA = sin(F_PI - phi);
+ if (fabsf(sinA) < 0.01f)
+ { //avoid division by zero
+ sinA = 0.01f;
+ }
+
+ F32 Plen = vars.dome_radius * sin(F_PI + phi + asin(vars.dome_offset * sinA)) / sinA;
+
+ Pn *= Plen;
+
+ // Set altitude
+ if (Pn[1] > 0.f)
+ {
+ Pn *= (max_y / Pn[1]);
+ }
+ else
+ {
+ Pn *= (-32000.f / Pn[1]);
+ }
+
+ Plen = Pn.length();
+ Pn /= Plen;
+
+ // Initialize temp variables
+ LLColor3 sunlight = vars.sunlight;
+ LLColor3 ambient = vars.ambient;
+
+ LLColor3 glow = vars.glow;
+ F32 cloud_shadow = vars.cloud_shadow;
+
+ // Sunlight attenuation effect (hue and brightness) due to atmosphere
+ // this is used later for sunlight modulation at various altitudes
+ LLColor3 light_atten = vars.light_atten;
+ LLColor3 light_transmittance = psky->getLightTransmittance(Plen);
+ (void)light_transmittance; // silence Clang warn-error
+
+ // Calculate relative weights
+ LLColor3 temp2(0.f, 0.f, 0.f);
+ LLColor3 temp1 = vars.total_density;
+
+ LLColor3 blue_weight = componentDiv(blue_density, temp1);
+ LLColor3 blue_factor = blue_horizon * blue_weight;
+ LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
+ LLColor3 haze_factor = haze_horizon * haze_weight;
+
+
+ // Compute sunlight from P & lightnorm (for long rays like sky)
+ temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + sun_norm.mV[1] );
+
+ temp2.mV[1] = 1.f / temp2.mV[1];
+ componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
+ componentMultBy(sunlight, light_transmittance);
+
+ // Distance
+ temp2.mV[2] = Plen * density_multiplier;
+
+ // Transparency (-> temp1)
+ temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
+
+ // Compute haze glow
+ temp2.mV[0] = Pn * LLVector3(sun_norm);
+
+ temp2.mV[0] = 1.f - temp2.mV[0];
+ // temp2.x is 0 at the sun and increases away from sun
+ temp2.mV[0] = llmax(temp2.mV[0], .001f);
+ // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+
+ // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ temp2.mV[0] *= glow.mV[0];
+
+ temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]);
+ // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ // Add "minimum anti-solar illumination"
+ temp2.mV[0] += .25f;
+
+
+ // Haze color above cloud
+ vars.hazeColor = (blue_factor * (sunlight + ambient) + componentMult(haze_factor, sunlight * temp2.mV[0] + ambient));
+
+ // Increase ambient when there are more clouds
+ LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f;
+
+ // Dim sunlight by cloud shadow percentage
+ sunlight *= (1.f - cloud_shadow);
+
+ // Haze color below cloud
+ vars.hazeColorBelowCloud = (blue_factor * (sunlight + tmpAmbient) + componentMult(haze_factor, sunlight * temp2.mV[0] + tmpAmbient));
+
+ // Final atmosphere additive
+ componentMultBy(vars.hazeColor, LLColor3::white - temp1);
+
+/*
+ // SL-12574
+
+ // Attenuate cloud color by atmosphere
+ temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds
+
+ // At horizon, blend high altitude sky color towards the darker color below the clouds
+ vars.hazeColor += componentMult(vars.hazeColorBelowCloud - vars.hazeColor, LLColor3::white - componentSqrt(temp1));
+*/
+}
+
+void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
+{
+ LLVector3 tosun = tosun_in;
+
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
+ {
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glFogf(GL_FOG_DENSITY, 0);
+ glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
+ glFogf(GL_FOG_END, 1000000.f);
+ }
+ 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;
+ // LLWorld::getInstance()->getWaterHeight();
+ F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
+
+ F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear();
+ camera_height += near_clip_height;
+
+ F32 fog_distance = 0.f;
+ LLColor3 res_color[3];
+
+ LLColor3 sky_fog_color = LLColor3::white;
+ LLColor3 render_fog_color = LLColor3::white;
+
+ const F32 tosun_z = tosun.mV[VZ];
+ tosun.mV[VZ] = 0.f;
+ tosun.normalize();
+ LLVector3 perp_tosun;
+ perp_tosun.mV[VX] = -tosun.mV[VY];
+ perp_tosun.mV[VY] = tosun.mV[VX];
+ LLVector3 tosun_45 = tosun + perp_tosun;
+ tosun_45.normalize();
+
+ F32 delta = 0.06f;
+ tosun.mV[VZ] = delta;
+ perp_tosun.mV[VZ] = delta;
+ tosun_45.mV[VZ] = delta;
+ tosun.normalize();
+ perp_tosun.normalize();
+ tosun_45.normalize();
+
+ // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun.
+ AtmosphericsVars vars;
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ // invariants across whole sky tex process...
+ vars.blue_density = psky->getBlueDensity();
+ vars.blue_horizon = psky->getBlueHorizon();
+ vars.haze_density = psky->getHazeDensity();
+ vars.haze_horizon = psky->getHazeHorizon();
+ vars.density_multiplier = psky->getDensityMultiplier();
+ vars.distance_multiplier = psky->getDistanceMultiplier();
+ vars.max_y = psky->getMaxY();
+ vars.sun_norm = LLEnvironment::instance().getSunDirectionCFR();
+ vars.sunlight = psky->getSunlightColor();
+ vars.ambient = psky->getAmbientColor();
+ vars.glow = psky->getGlow();
+ vars.cloud_shadow = psky->getCloudShadow();
+ vars.dome_radius = psky->getDomeRadius();
+ vars.dome_offset = psky->getDomeOffset();
+ vars.light_atten = psky->getLightAttenuation(vars.max_y);
+ vars.light_transmittance = psky->getLightTransmittance(vars.max_y);
+ vars.total_density = psky->getTotalDensity();
+ vars.gamma = psky->getGamma();
+
+ res_color[0] = calcSkyColorInDir(vars, tosun);
+ res_color[1] = calcSkyColorInDir(vars, perp_tosun);
+ res_color[2] = calcSkyColorInDir(vars, tosun_45);
+
+ sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
+
+ F32 full_off = -0.25f;
+ F32 full_on = 0.00f;
+ F32 on = (tosun_z - full_off) / (full_on - full_off);
+ on = llclamp(on, 0.01f, 1.f);
+ sky_fog_color *= 0.5f * on;
+
+
+ // We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ???
+ S32 i;
+ for (i = 0; i < 3; i++)
+ {
+ sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]);
+ }
+
+ color_gamma_correct(sky_fog_color);
+
+ 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);
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glFogfv(GL_FOG_COLOR, fog.mV);
+ }
+ 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;
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glFogi(GL_FOG_MODE, GL_EXP2);
+ }
+ }
+ else
+ {
+ const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
+ fog_density = (f_log)/fog_distance;
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glFogi(GL_FOG_MODE, GL_EXP);
+ }
+ }
+ }
+ 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());
+
+ // adjust the color based on depth. We're doing linear approximations
+ float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
+ float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),
+ gSavedSettings.getF32("WaterGLFogDepthFloor"));
+
+ LLColor4 fogCol = water_fog_color * depth_modifier;
+ fogCol.setAlpha(1);
+
+ // set the gl fog color
+ mGLFogCol = fogCol;
+
+ // set the density based on what the shaders use
+ fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
+ glFogi(GL_FOG_MODE, GL_EXP2);
+ }
+ }
+
+ mFogColor = sky_fog_color;
+ mFogColor.setAlpha(1);
+
+ LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ LLGLSFog gls_fog;
+ glFogf(GL_FOG_END, fog_distance*2.2f);
+ glFogf(GL_FOG_DENSITY, fog_density);
+ glHint(GL_FOG_HINT, GL_NICEST);
+ }
+ stop_glerror();
+}
+
+// Functions used a lot.
+F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
+{
+ F32 mv = color_max(col);
+ if (0 == mv)
+ {
+ return 0;
+ }
+
+ col *= 1.f / mv;
+ color_pow(col, e);
+ if (postmultiply)
+ {
+ col *= mv;
+ }
+ return mv;
+}
+
+// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis.
+// Range of output is 0.0f to 2pi //359.99999...f
+// Returns 0.0f when "v" = +/- z_axis.
+F32 azimuth(const LLVector3 &v)
+{
+ F32 azimuth = 0.0f;
+ if (v.mV[VX] == 0.0f)
+ {
+ if (v.mV[VY] > 0.0f)
+ {
+ azimuth = F_PI * 0.5f;
+ }
+ else if (v.mV[VY] < 0.0f)
+ {
+ azimuth = F_PI * 1.5f;// 270.f;
+ }
+ }
+ else
+ {
+ azimuth = (F32) atan(v.mV[VY] / v.mV[VX]);
+ if (v.mV[VX] < 0.0f)
+ {
+ azimuth += F_PI;
+ }
+ else if (v.mV[VY] < 0.0f)
+ {
+ azimuth += F_PI * 2;
+ }
+ }
+ return azimuth;
+}
+
+bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b)
+{
+ if (a.hazeColor != b.hazeColor)
+ {
+ return false;
+ }
+
+ if (a.hazeColorBelowCloud != b.hazeColorBelowCloud)
+ {
+ return false;
+ }
+
+ if (a.cloudColorSun != b.cloudColorSun)
+ {
+ return false;
+ }
+
+ if (a.cloudColorAmbient != b.cloudColorAmbient)
+ {
+ return false;
+ }
+
+ if (a.cloudDensity != b.cloudDensity)
+ {
+ return false;
+ }
+
+ if (a.density_multiplier != b.density_multiplier)
+ {
+ return false;
+ }
+
+ if (a.haze_horizon != b.haze_horizon)
+ {
+ return false;
+ }
+
+ if (a.haze_density != b.haze_density)
+ {
+ return false;
+ }
+
+ if (a.blue_horizon != b.blue_horizon)
+ {
+ return false;
+ }
+
+ if (a.blue_density != b.blue_density)
+ {
+ return false;
+ }
+
+ if (a.dome_offset != b.dome_offset)
+ {
+ return false;
+ }
+
+ if (a.dome_radius != b.dome_radius)
+ {
+ return false;
+ }
+
+ if (a.cloud_shadow != b.cloud_shadow)
+ {
+ return false;
+ }
+
+ if (a.glow != b.glow)
+ {
+ return false;
+ }
+
+ if (a.ambient != b.ambient)
+ {
+ return false;
+ }
+
+ if (a.sunlight != b.sunlight)
+ {
+ return false;
+ }
+
+ if (a.sun_norm != b.sun_norm)
+ {
+ return false;
+ }
+
+ if (a.gamma != b.gamma)
+ {
+ return false;
+ }
+
+ if (a.max_y != b.max_y)
+ {
+ return false;
+ }
+
+ if (a.distance_multiplier != b.distance_multiplier)
+ {
+ return false;
+ }
+
+ // light_atten, light_transmittance, total_density
+ // are ignored as they always change when the values above do
+ // they're just shared calc across the sky map generation to save cycles
+
+ return true;
+}
+
+bool approximatelyEqual(const F32 &a, const F32 &b, const F32 &fraction_treshold)
+{
+ F32 diff = fabs(a - b);
+ if (diff < F_APPROXIMATELY_ZERO || diff < llmax(fabs(a), fabs(b)) * fraction_treshold)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool approximatelyEqual(const LLColor3 &a, const LLColor3 &b, const F32 &fraction_treshold)
+{
+ return approximatelyEqual(a.mV[0], b.mV[0], fraction_treshold)
+ && approximatelyEqual(a.mV[1], b.mV[1], fraction_treshold)
+ && approximatelyEqual(a.mV[2], b.mV[2], fraction_treshold);
+}
+
+bool approximatelyEqual(const LLVector4 &a, const LLVector4 &b, const F32 &fraction_treshold)
+{
+ return approximatelyEqual(a.mV[0], b.mV[0], fraction_treshold)
+ && approximatelyEqual(a.mV[1], b.mV[1], fraction_treshold)
+ && approximatelyEqual(a.mV[2], b.mV[2], fraction_treshold)
+ && approximatelyEqual(a.mV[3], b.mV[3], fraction_treshold);
+}
+
+bool approximatelyEqual(const AtmosphericsVars& a, const AtmosphericsVars& b, const F32 fraction_treshold)
+{
+ if (!approximatelyEqual(a.hazeColor, b.hazeColor, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.hazeColorBelowCloud, b.hazeColorBelowCloud, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.cloudColorSun, b.cloudColorSun, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.cloudColorAmbient, b.cloudColorAmbient, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.cloudDensity, b.cloudDensity, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.density_multiplier, b.density_multiplier, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.haze_horizon, b.haze_horizon, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.haze_density, b.haze_density, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.blue_horizon, b.blue_horizon, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.blue_density, b.blue_density, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.dome_offset, b.dome_offset, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.dome_radius, b.dome_radius, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.cloud_shadow, b.cloud_shadow, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.glow, b.glow, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.ambient, b.ambient, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.sunlight, b.sunlight, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.sun_norm, b.sun_norm, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.gamma, b.gamma, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.max_y, b.max_y, fraction_treshold))
+ {
+ return false;
+ }
+
+ if (!approximatelyEqual(a.distance_multiplier, b.distance_multiplier, fraction_treshold))
+ {
+ return false;
+ }
+
+ // light_atten, light_transmittance, total_density
+ // are ignored as they always change when the values above do
+ // they're just shared calc across the sky map generation to save cycles
+
+ return true;
+}
+
diff --git a/indra/newview/lllegacyatmospherics.h b/indra/newview/lllegacyatmospherics.h
new file mode 100644
index 0000000000..03c8efb91a
--- /dev/null
+++ b/indra/newview/lllegacyatmospherics.h
@@ -0,0 +1,284 @@
+/**
+ * @file lllegacyatmospherics.h
+ * @brief LLVOSky class header file
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLEGACYATMOSPHERICS_H
+#define LL_LLLEGACYATMOSPHERICS_H
+
+#include "stdtypes.h"
+#include "v3color.h"
+#include "v4coloru.h"
+#include "llviewertexture.h"
+#include "llviewerobject.h"
+#include "llframetimer.h"
+#include "v3colorutil.h"
+#include "llsettingssky.h"
+
+//////////////////////////////////
+//
+// Lots of constants
+//
+// Will clean these up at some point...
+//
+
+const F32 HORIZON_DIST = 1024.0f;
+const F32 ATM_EXP_FALLOFF = 0.000126f;
+const F32 ATM_SEA_LEVEL_NDENS = 2.55e25f;
+const F32 ATM_HEIGHT = 100000.f;
+
+// constants used in calculation of scattering coeff of clear air
+const F32 sigma = 0.035f;
+const F32 fsigma = (6.f + 3.f * sigma) / (6.f-7.f*sigma);
+const F64 Ndens = 2.55e25;
+const F64 Ndens2 = Ndens*Ndens;
+
+class LLFace;
+class LLHaze;
+
+LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length)
+{
+ LLColor3 refr_ind;
+ for (S32 i = 0; i < 3; ++i)
+ {
+ const F32 wl2 = wave_length.mV[i] * wave_length.mV[i] * 1e-6f;
+ refr_ind.mV[i] = 6.43e3f + ( 2.95e6f / ( 146.0f - 1.f/wl2 ) ) + ( 2.55e4f / ( 41.0f - 1.f/wl2 ) );
+ refr_ind.mV[i] *= 1.0e-8f;
+ refr_ind.mV[i] += 1.f;
+ }
+ return refr_ind;
+}
+
+
+class LLHaze
+{
+public:
+ LLHaze() : mG(0), mFalloff(1), mAbsCoef(0.f) {mSigSca.setToBlack();}
+ LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) :
+ mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f)
+ {
+ mAbsCoef = color_intens(mSigSca) / sAirScaIntense;
+ }
+
+ LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g),
+ mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo)
+ {
+ mAbsCoef = 0.01f * sca / sAirScaAvg;
+ }
+
+/* Proportion of light that is scattered into 'path' from 'in' over distance dt. */
+/* assumes that vectors 'path' and 'in' are normalized. Scattering coef / 2pi */
+
+ LL_FORCE_INLINE LLColor3 calcAirSca(const F32 h)
+ {
+ return calcFalloff(h) * sAirScaSeaLevel;
+ }
+
+ LL_FORCE_INLINE void calcAirSca(const F32 h, LLColor3 &result)
+ {
+ result = sAirScaSeaLevel;
+ result *= calcFalloff(h);
+ }
+
+ F32 getG() const { return mG; }
+
+ void setG(const F32 g)
+ {
+ mG = g;
+ }
+
+ const LLColor3& getSigSca() const // sea level
+ {
+ return mSigSca;
+ }
+
+ void setSigSca(const LLColor3& s)
+ {
+ mSigSca = s;
+ mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense;
+ }
+
+ void setSigSca(const F32 s0, const F32 s1, const F32 s2)
+ {
+ mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2);
+ mAbsCoef = 0.01f * (s0 + s1 + s2) / 3;
+ }
+
+ F32 getFalloff() const
+ {
+ return mFalloff;
+ }
+
+ void setFalloff(const F32 fo)
+ {
+ mFalloff = fo;
+ }
+
+ F32 getAbsCoef() const
+ {
+ return mAbsCoef;
+ }
+
+ inline static F32 calcFalloff(const F32 h)
+ {
+ return (h <= 0) ? 1.0f : (F32)LL_FAST_EXP(-ATM_EXP_FALLOFF * h);
+ }
+
+ inline LLColor3 calcSigSca(const F32 h) const
+ {
+ return calcFalloff(h * mFalloff) * mSigSca;
+ }
+
+ inline void calcSigSca(const F32 h, LLColor3 &result) const
+ {
+ result = mSigSca;
+ result *= calcFalloff(h * mFalloff);
+ }
+
+ LLColor3 calcSigExt(const F32 h) const
+ {
+ return calcFalloff(h * mFalloff) * (1 + mAbsCoef) * mSigSca;
+ }
+
+ F32 calcPhase(const F32 cos_theta) const;
+
+private:
+ static LLColor3 const sAirScaSeaLevel;
+ static F32 const sAirScaIntense;
+ static F32 const sAirScaAvg;
+
+protected:
+ F32 mG;
+ LLColor3 mSigSca;
+ F32 mFalloff; // 1 - slow, >1 - faster
+ F32 mAbsCoef;
+};
+
+
+class LLCubeMap;
+
+class AtmosphericsVars
+{
+public:
+ AtmosphericsVars()
+ : hazeColor(0,0,0)
+ , hazeColorBelowCloud(0,0,0)
+ , cloudColorSun(0,0,0)
+ , cloudColorAmbient(0,0,0)
+ , cloudDensity(0.0f)
+ , blue_density()
+ , blue_horizon()
+ , haze_density(0.0f)
+ , haze_horizon(0.0f)
+ , density_multiplier(0.0f)
+ , max_y(0.0f)
+ , gamma(1.0f)
+ , sun_norm(0.0f, 1.0f, 0.0f, 1.0f)
+ , sunlight()
+ , ambient()
+ , glow()
+ , cloud_shadow(1.0f)
+ , dome_radius(1.0f)
+ , dome_offset(1.0f)
+ , light_atten()
+ , light_transmittance()
+ {
+ }
+
+ friend bool operator==(const AtmosphericsVars& a, const AtmosphericsVars& b);
+ // returns true if values are within treshold of each other.
+ friend bool approximatelyEqual(const AtmosphericsVars& a, const AtmosphericsVars& b, const F32 fraction_treshold);
+
+ LLColor3 hazeColor;
+ LLColor3 hazeColorBelowCloud;
+ LLColor3 cloudColorSun;
+ LLColor3 cloudColorAmbient;
+ F32 cloudDensity;
+ LLColor3 blue_density;
+ LLColor3 blue_horizon;
+ F32 haze_density;
+ F32 haze_horizon;
+ F32 density_multiplier;
+ F32 distance_multiplier;
+ F32 max_y;
+ F32 gamma;
+ LLVector4 sun_norm;
+ LLColor3 sunlight;
+ LLColor3 ambient;
+ LLColor3 glow;
+ F32 cloud_shadow;
+ F32 dome_radius;
+ F32 dome_offset;
+ LLColor3 light_atten;
+ LLColor3 light_transmittance;
+ LLColor3 total_density;
+};
+
+class LLAtmospherics
+{
+public:
+ LLAtmospherics();
+ ~LLAtmospherics();
+
+ void init();
+ void updateFog(const F32 distance, const LLVector3& tosun);
+
+ const LLHaze& getHaze() const { return mHaze; }
+ LLHaze& getHaze() { return mHaze; }
+ F32 getHazeConcentration() const { return mHazeConcentration; }
+ void setHaze(const LLHaze& h) { mHaze = h; }
+ void setFogRatio(const F32 fog_ratio) { mFogRatio = fog_ratio; }
+
+ F32 getFogRatio() const { return mFogRatio; }
+ LLColor4 getFogColor() const { return mFogColor; }
+ LLColor4 getGLFogColor() const { return mGLFogCol; }
+
+ void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; }
+ void setWind ( const LLVector3& wind ) { mWind = wind.length(); }
+
+ LLColor4 calcSkyColorInDir(AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false);
+ LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t &psky, AtmosphericsVars& vars, const LLVector3& dir, bool isShiny = false);
+
+protected:
+
+ void calcSkyColorWLVert(const LLSettingsSky::ptr_t &psky, LLVector3 & Pn, AtmosphericsVars& vars);
+ LLColor3 getHazeColor(LLSettingsSky::ptr_t psky, AtmosphericsVars& vars, F32 costheta, F32 cloud_shadow);
+
+ LLHaze mHaze;
+ F32 mHazeConcentration;
+ F32 mCloudDensity;
+ F32 mWind;
+ BOOL mInitialized;
+ LLVector3 mLastLightingDirection;
+ LLColor3 mLastTotalAmbient;
+ F32 mAmbientScale;
+ LLColor3 mNightColorShift;
+ F32 mInterpVal;
+ LLColor4 mFogColor;
+ LLColor4 mGLFogCol;
+ F32 mFogRatio;
+ F32 mWorldScale;
+};
+
+#endif
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index b8bde39bd1..5a17332fde 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -1038,6 +1038,19 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)
return world_id;
}
+bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)
+{
+ for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ {
+ LLLocalBitmap* unit = *iter;
+ if (unit->getWorldID() == world_id)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)
{
std::string filename = "";
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index f6cc1e919e..d5ee7efdc6 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -120,6 +120,7 @@ public:
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);
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 42b5ff3890..d6f3068610 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -44,7 +44,7 @@
// newview includes
#include "llagent.h"
-#include "llenvmanager.h"
+#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
@@ -297,7 +297,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
LLButton::Params maturity_button = p.maturity_button;
mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
addChild(mMaturityButton);
- mMaturityButton->setClickedCallback(boost::bind(&LLLocationInputCtrl::onMaturityButtonClicked, this));
LLButton::Params for_sale_button = p.for_sale_button;
for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip");
@@ -655,7 +654,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked()
}
else
{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+ LLFloaterReg::showInstance("add_landmark");
}
}
@@ -664,11 +663,6 @@ void LLLocationInputCtrl::onAgentParcelChange()
refresh();
}
-void LLLocationInputCtrl::onMaturityButtonClicked()
-{
- LLUI::getInstance()->mHelpImpl->showTopic(mMaturityHelpTopic);
-}
-
void LLLocationInputCtrl::onRegionBoundaryCrossed()
{
createNavMeshStatusListenerForCurrentRegion();
@@ -1100,9 +1094,7 @@ void LLLocationInputCtrl::changeLocationPresentation()
//change location presentation only if user does not select/paste anything and
//human-readable region name is being displayed
- std::string text = mTextEntry->getText();
- LLStringUtil::trim(text);
- if(!mTextEntry->hasSelection() && text == mHumanReadableLocation)
+ if(!mTextEntry->hasSelection() && mTextEntry->getText() == mHumanReadableLocation)
{
//needs unescaped one
LLSLURL slurl;
@@ -1135,7 +1127,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
if(!landmark)
{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+ LLFloaterReg::showInstance("add_landmark");
}
else
{
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index da71bab6c1..79dbe17982 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -160,7 +160,6 @@ private:
void onForSaleButtonClicked();
void onAddLandmarkButtonClicked();
void onAgentParcelChange();
- void onMaturityButtonClicked();
void onRegionBoundaryCrossed();
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
// callbacks
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 453bf17b11..eebc2486a2 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -67,6 +67,8 @@ const std::string LL_IM_FROM("from");
const std::string LL_IM_FROM_ID("from_id");
const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
+const std::string GROUP_CHAT_SUFFIX(" (group)");
+
const static char IM_SYMBOL_SEPARATOR(':');
const static std::string IM_SEPARATOR(std::string() + IM_SYMBOL_SEPARATOR + " ");
const static std::string NEW_LINE("\n");
@@ -131,6 +133,16 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
messages.back()[LL_IM_TEXT] = im_text;
}
+std::string remove_utf8_bom(const char* buf)
+{
+ std::string res(buf);
+ if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
+ {
+ res.erase(0, 3);
+ }
+ return res;
+}
+
class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
{
LLSINGLETON(LLLogChatTimeScanner);
@@ -269,6 +281,28 @@ std::string LLLogChat::makeLogFileName(std::string filename)
return filename;
}
+//static
+void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename)
+{
+ std::string new_name = cleanFileName(new_filename);
+ std::string old_name = cleanFileName(old_filename);
+ new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name);
+ old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name);
+
+ if (new_name.empty() || old_name.empty())
+ {
+ return;
+ }
+
+ new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+ old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
+ if (!LLFile::isfile(new_name) && LLFile::isfile(old_name))
+ {
+ LLFile::rename(old_name, new_name);
+ }
+}
+
std::string LLLogChat::cleanFileName(std::string filename)
{
std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
@@ -355,7 +389,7 @@ void LLLogChat::saveHistory(const std::string& filename,
}
// static
-void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
+void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params, bool is_group)
{
if (file_name.empty())
{
@@ -368,10 +402,25 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (is_group)
+ {
+ std::string old_name(file_name);
+ old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
+ if (fptr)
+ {
+ fclose(fptr);
+ LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
+ }
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
+ }
if (!fptr)
{
- return; //No previous conversation with this name.
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ return; //No previous conversation with this name.
+ }
}
}
@@ -400,7 +449,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
continue;
}
- std::string line(buffer);
+ std::string line(remove_utf8_bom(buffer));
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
if (' ' == line[0])
@@ -744,8 +793,8 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group)
{
std::string file_name;
gCacheName->getGroupName(avatar_id, file_name);
- file_name = makeLogFileName(file_name);
- return isTranscriptFileFound(makeLogFileName(file_name));
+ file_name = makeLogFileName(file_name + GROUP_CHAT_SUFFIX);
+ return isTranscriptFileFound(file_name);
}
return false;
}
@@ -788,7 +837,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
{
//matching a timestamp
boost::match_results<std::string::const_iterator> matches;
- if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+ if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
{
result = true;
}
@@ -1053,12 +1102,28 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ bool is_group = load_params.has("is_group") ? load_params["is_group"].asBoolean() : false;
+ if (is_group)
+ {
+ std::string old_name(file_name);
+ old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
+ if (fptr)
+ {
+ fclose(fptr);
+ LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
+ }
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
+ }
if (!fptr)
{
- mNewLoad = false;
- (*mLoadEndSignal)(messages, file_name);
- return; //No previous conversation with this name.
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ mNewLoad = false;
+ (*mLoadEndSignal)(messages, file_name);
+ return; //No previous conversation with this name.
+ }
}
}
@@ -1093,7 +1158,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
firstline = FALSE;
continue;
}
- std::string line(buffer);
+ std::string line(remove_utf8_bom(buffer));
//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
if (' ' == line[0])
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index b71a34ae0a..c4b61ee716 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -94,6 +94,7 @@ public:
static std::string timestamp(bool withdate = false);
static std::string makeLogFileName(std::string(filename));
+ static void renameLogFile(const std::string& old_filename, const std::string& new_filename);
/**
*Add functions to get old and non date stamped file names when needed
*/
@@ -106,7 +107,7 @@ public:
static void getListOfTranscriptFiles(std::vector<std::string>& list);
static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
- static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+ static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD(), bool is_group = false);
typedef boost::signals2::signal<void ()> save_history_signal_t;
boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
@@ -196,6 +197,7 @@ protected:
virtual ~LLChatLogParser() {};
};
+extern const std::string GROUP_CHAT_SUFFIX;
// LLSD map lookup constants
extern const std::string LL_IM_TIME; //("time");
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index eca34c0d4d..22cedf450e 100644
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -139,8 +139,11 @@ LLPointer<LLCredential> LLLoginHandler::initializeLoginInfo()
// so try to load it from the UserLoginInfo
result = loadSavedUserLoginInfo();
if (result.isNull())
- {
- result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ {
+ // Since legacy viewer store login info one per grid, newer viewers have to
+ // reuse same information to remember last user and for compatibility,
+ // but otherwise login info is stored in separate map in gSecAPIHandler
+ result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
return result;
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 8a69acb8dc..e81d2cc082 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -58,11 +58,12 @@
#include "llevents.h"
#include "llappviewer.h"
#include "llsdserialize.h"
+#include "lltrans.h"
#include <boost/scoped_ptr.hpp>
#include <sstream>
-const S32 LOGIN_MAX_RETRIES = 3;
+const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login
const F32 LOGIN_SRV_TIMEOUT_MIN = 10;
const F32 LOGIN_SRV_TIMEOUT_MAX = 120;
const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time
@@ -215,8 +216,8 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["last_exec_event"] = mLastExecEvent;
request_params["last_exec_duration"] = mLastExecDuration;
request_params["mac"] = (char*)hashed_unique_id_string;
- request_params["version"] = LLVersionInfo::getVersion();
- request_params["channel"] = LLVersionInfo::getChannel();
+ request_params["version"] = LLVersionInfo::instance().getVersion();
+ request_params["channel"] = LLVersionInfo::instance().getChannel();
request_params["platform"] = mPlatform;
request_params["address_size"] = ADDRESS_SIZE;
request_params["platform_version"] = mPlatformVersion;
@@ -332,7 +333,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
{
data["certificate"] = response["certificate"];
}
-
+
if (gViewerWindow)
gViewerWindow->setShowProgress(FALSE);
@@ -349,13 +350,36 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
// login.cgi is insisting on a required update. We were called with an
// event that bundles both the login.cgi 'response' and the
// synchronization event from the 'updater'.
- std::string required_version = response["message_args"]["VERSION"];
- LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
+ std::string login_version = response["message_args"]["VERSION"];
+ std::string vvm_version = updater["VERSION"];
+ std::string relnotes = updater["URL"];
+ LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL;
+ // vvm_version might be empty because we might not have gotten
+ // SLVersionChecker's LoginSync handshake. But if it IS populated, it
+ // should (!) be the same as the version we got from login.cgi.
+ if ((! vvm_version.empty()) && vvm_version != login_version)
+ {
+ LL_WARNS("LLLogin") << "VVM update version " << vvm_version
+ << " differs from login version " << login_version
+ << "; presenting VVM version to match release notes URL"
+ << LL_ENDL;
+ login_version = vvm_version;
+ }
+ if (relnotes.empty() || relnotes.find("://") == std::string::npos)
+ {
+ relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+ if (!LLStringUtil::endsWith(relnotes, "/"))
+ relnotes += "/";
+ relnotes += LLURI::escape(login_version) + ".html";
+ }
if (gViewerWindow)
gViewerWindow->setShowProgress(FALSE);
- LLSD args(LLSDMap("VERSION", required_version));
+ LLSD args;
+ args["VERSION"] = login_version;
+ args["URL"] = relnotes;
+
if (updater.isUndefined())
{
// If the updater failed to shake hands, better advise the user to
@@ -427,6 +451,7 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
LL_INFOS("LLLogin") << "LLLoginInstance::handleLoginSuccess" << LL_ENDL;
attemptComplete();
+ mRequestData.clear();
}
void LLLoginInstance::handleDisconnect(const LLSD& event)
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index 51127928d1..57a6ecb604 100644
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -237,7 +237,7 @@ S32 LLMachineID::init()
{
if (j >= serial_size || vtProp.bstrVal[j] == 0)
break;
-
+
static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]);
j++;
}
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index f158aae3d2..c3e39429a2 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -447,6 +447,7 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
}
mMouseCur = mMouseDown;
+ mAgentSelfAtAxis = gAgent.getAtAxis(); // no point checking if avatar was selected, just save the value
// Route future Mouse messages here preemptively. (Release on mouse up.)
setMouseCapture( TRUE );
@@ -610,6 +611,26 @@ void LLManipRotate::drag( S32 x, S32 y )
else
{
object->setRotation(new_rot, damped);
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar && avatar->isSelf()
+ && LLSelectMgr::getInstance()->mAllowSelectAvatar
+ && !object->getParent())
+ {
+ // Normal avatars use object's orienttion, but self uses
+ // separate LLCoordFrame
+ // See LVOAvatar::updateOrientation()
+ if (gAgentCamera.getFocusOnAvatar())
+ {
+ //Don't rotate camera with avatar
+ gAgentCamera.setFocusOnAvatar(false, false, false);
+ }
+
+ LLVector3 at_axis = mAgentSelfAtAxis;
+ at_axis *= mRotation;
+ at_axis.mV[VZ] = 0.f;
+ at_axis.normalize();
+ gAgent.resetAxes(at_axis);
+ }
rebuild(object);
}
@@ -717,7 +738,7 @@ void LLManipRotate::drag( S32 x, S32 y )
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
- !cur->isAvatar())
+ (!cur->isAvatar() || LLSelectMgr::getInstance()->mAllowSelectAvatar))
{
selectNode->mLastRotation = cur->getRotation();
selectNode->mLastPositionLocal = cur->getPosition();
diff --git a/indra/newview/llmaniprotate.h b/indra/newview/llmaniprotate.h
index e8f1c24c58..dc36ef796a 100644
--- a/indra/newview/llmaniprotate.h
+++ b/indra/newview/llmaniprotate.h
@@ -95,6 +95,7 @@ private:
LLVector3 mMouseDown;
LLVector3 mMouseCur;
+ LLVector3 mAgentSelfAtAxis; // Own agent uses separate rotation method
F32 mRadiusMeters;
LLVector3 mCenterToCam;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 805c25508f..aa0c7fb73b 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -1294,6 +1294,11 @@ void LLMarketplaceData::setSLMDataFetched(U32 status)
}
}
+bool LLMarketplaceData::isSLMDataFetched()
+{
+ return mMarketPlaceDataFetched == MarketplaceFetchCodes::MARKET_FETCH_DONE;
+}
+
// Creation / Deletion / Update
// Methods publicly called
bool LLMarketplaceData::createListing(const LLUUID& folder_id)
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index ec312baca3..fee9225f77 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -204,7 +204,9 @@ public:
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
void setSLMDataFetched(U32 status);
U32 getSLMDataFetched() { return mMarketPlaceDataFetched; }
-
+
+ bool isSLMDataFetched();
+
// High level create/delete/set Marketplace data: each method returns true if the function succeeds, false if error
bool createListing(const LLUUID& folder_id);
bool activateListing(const LLUUID& folder_id, bool activate, S32 depth = -1);
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index b399ab9bc4..0affe8efb4 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -202,12 +202,29 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
- mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE));
+ }
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ if (LLPanel::handleScrollHWheel(x, y, clicks)) return TRUE;
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(TRUE));
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// virtual
BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask)
{
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 11400c8274..958c76f261 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -92,6 +92,7 @@ public:
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+ virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
// navigation
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
index 63d97f6ac2..0663dd41ee 100644
--- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -34,7 +34,6 @@
#include <boost/signals2.hpp>
#include "llagent.h"
-#include "llenvmanager.h"
#include "llnotificationsutil.h"
#include "llpathfindingmanager.h"
#include "llpathfindingnavmesh.h"
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 31e3d408d7..3e8731dfe6 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -41,7 +41,6 @@
#include "lldeadmantimer.h"
#include "llfloatermodelpreview.h"
#include "llfloaterperms.h"
-#include "lleconomy.h"
#include "llimagej2c.h"
#include "llhost.h"
#include "llmath.h"
@@ -100,7 +99,7 @@
// locking actions. In particular, the following operations
// on LLMeshRepository are very averse to any stalls:
// * loadMesh
-// * getMeshHeader (For structural details, see:
+// * search in mMeshHeader (For structural details, see:
// http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format)
// * notifyLoadedMeshes
// * getSkinInfo
@@ -877,7 +876,7 @@ LLMeshRepoThread::~LLMeshRepoThread()
void LLMeshRepoThread::run()
{
LLCDResult res = LLConvexDecomposition::initThread();
- if (res != LLCD_OK)
+ if (res != LLCD_OK && LLConvexDecomposition::isFunctional())
{
LL_WARNS(LOG_MESH) << "Convex decomposition unable to be loaded. Expect severe problems." << LL_ENDL;
}
@@ -1143,7 +1142,7 @@ void LLMeshRepoThread::run()
}
res = LLConvexDecomposition::quitThread();
- if (res != LLCD_OK)
+ if (res != LLCD_OK && LLConvexDecomposition::isFunctional())
{
LL_WARNS(LOG_MESH) << "Convex decomposition unable to be quit." << LL_ENDL;
}
@@ -1554,7 +1553,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
if (!zero)
{ //attempt to parse
- if (physicsShapeReceived(mesh_id, buffer, size))
+ if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK)
{
delete[] buffer;
return true;
@@ -1648,7 +1647,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c
LLMeshRepository::sCacheBytesRead += bytes;
++LLMeshRepository::sCacheReads;
file.read(buffer, bytes);
- if (headerReceived(mesh_params, buffer, bytes))
+ if (headerReceived(mesh_params, buffer, bytes) == MESH_OK)
{
// Found mesh in VFS cache
return true;
@@ -1795,7 +1794,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
return retval;
}
-bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
+EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
{
const LLUUID mesh_id = mesh_params.getSculptID();
LLSD header;
@@ -1803,30 +1802,39 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
U32 header_size = 0;
if (data_size > 0)
{
- std::string res_str((char*) data, data_size);
+ std::istringstream stream;
+ try
+ {
+ std::string res_str((char*)data, data_size);
- std::string deprecated_header("<? LLSD/Binary ?>");
+ std::string deprecated_header("<? LLSD/Binary ?>");
- if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
- {
- res_str = res_str.substr(deprecated_header.size()+1, data_size);
- header_size = deprecated_header.size()+1;
- }
- data_size = res_str.size();
+ if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
+ {
+ res_str = res_str.substr(deprecated_header.size() + 1, data_size);
+ header_size = deprecated_header.size() + 1;
+ }
+ data_size = res_str.size();
- std::istringstream stream(res_str);
+ stream.str(res_str);
+ }
+ catch (std::bad_alloc&)
+ {
+ // out of memory, we won't be able to process this mesh
+ return MESH_OUT_OF_MEMORY;
+ }
if (!LLSDSerialize::fromBinary(header, stream, data_size))
{
LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id
<< LL_ENDL;
- return false;
+ return MESH_PARSE_FAILURE;
}
if (!header.isMap())
{
LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
- return false;
+ return MESH_INVALID;
}
if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)
@@ -1872,7 +1880,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
}
}
- return true;
+ return MESH_OK;
}
EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
@@ -1889,7 +1897,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
std::string mesh_string((char*)data, data_size);
stream.str(mesh_string);
}
- catch (std::bad_alloc)
+ catch (std::bad_alloc&)
{
// out of memory, we won't be able to process this mesh
return MESH_OUT_OF_MEMORY;
@@ -1903,6 +1911,12 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
{
LLMutexLock lock(mMutex);
mLoadedQ.push(mesh);
+ // LLPointer is not thread safe, since we added this pointer into
+ // threaded list, make sure counter gets decreased inside mutex lock
+ // and won't affect mLoadedQ processing
+ volume = NULL;
+ // might be good idea to turn mesh into pointer to avoid making a copy
+ mesh.mVolume = NULL;
}
return MESH_OK;
}
@@ -1917,18 +1931,25 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
if (data_size > 0)
{
- std::string res_str((char*) data, data_size);
-
- std::istringstream stream(res_str);
+ try
+ {
+ std::string res_str((char*)data, data_size);
+ std::istringstream stream(res_str);
- U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
- if (uzip_result != LLUZipHelper::ZR_OK)
- {
- LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id
- << " uzip result" << uzip_result
- << LL_ENDL;
- return false;
- }
+ U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
+ if (uzip_result != LLUZipHelper::ZR_OK)
+ {
+ LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id
+ << " uzip result" << uzip_result
+ << LL_ENDL;
+ return false;
+ }
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
+ return false;
+ }
}
{
@@ -1950,19 +1971,26 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
LLSD decomp;
if (data_size > 0)
- {
- std::string res_str((char*) data, data_size);
-
- std::istringstream stream(res_str);
+ {
+ try
+ {
+ std::string res_str((char*)data, data_size);
+ std::istringstream stream(res_str);
- U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
- if (uzip_result != LLUZipHelper::ZR_OK)
- {
- LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id
- << " uzip result: " << uzip_result
- << LL_ENDL;
- return false;
- }
+ U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
+ if (uzip_result != LLUZipHelper::ZR_OK)
+ {
+ LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id
+ << " uzip result: " << uzip_result
+ << LL_ENDL;
+ return false;
+ }
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
+ return false;
+ }
}
{
@@ -1977,7 +2005,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
return true;
}
-bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
+EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size)
{
LLSD physics_shape;
@@ -1994,8 +2022,19 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
LLPointer<LLVolume> volume = new LLVolume(volume_params,0);
- std::string mesh_string((char*) data, data_size);
- std::istringstream stream(mesh_string);
+
+ std::istringstream stream;
+ try
+ {
+ std::string mesh_string((char*)data, data_size);
+ stream.str(mesh_string);
+ }
+ catch (std::bad_alloc&)
+ {
+ // out of memory, we won't be able to process this mesh
+ delete d;
+ return MESH_OUT_OF_MEMORY;
+ }
if (volume->unpackVolumeFaces(stream, data_size))
{
@@ -2034,7 +2073,7 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
LLMutexLock lock(mMutex);
mDecompositionQ.push_back(d);
}
- return true;
+ return MESH_OK;
}
LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures,
@@ -2772,7 +2811,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
if (observer)
{
- observer->setModelPhysicsFeeErrorStatus(status.toULong(), reason);
+ observer->setModelPhysicsFeeErrorStatus(status.toULong(), reason, body["error"]);
}
}
else
@@ -2805,7 +2844,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp
if (observer)
{
- observer->setModelPhysicsFeeErrorStatus(status.toULong(), reason);
+ observer->setModelPhysicsFeeErrorStatus(status.toULong(), reason, body["error"]);
}
}
}
@@ -2830,12 +2869,12 @@ void LLMeshRepoThread::notifyLoadedMeshes()
mMutex->unlock();
break;
}
- LoadedMesh mesh = mLoadedQ.front();
+ LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point
mLoadedQ.pop();
mMutex->unlock();
update_metrics = true;
- if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0)
+ if (mesh.mVolume->getNumVolumeFaces() > 0)
{
gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
}
@@ -3143,15 +3182,21 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
U8 * data, S32 data_size)
{
LLUUID mesh_id = mMeshParams.getSculptID();
- bool success = (! MESH_HEADER_PROCESS_FAILED)
- && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
- && gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+ bool success = (!MESH_HEADER_PROCESS_FAILED)
+ && ((data != NULL) == (data_size > 0)); // if we have data but no size or have size but no data, something is wrong;
llassert(success);
+ EMeshProcessingResult res = MESH_UNKNOWN;
+ if (success)
+ {
+ res = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+ success = (res == MESH_OK);
+ }
if (! success)
{
// *TODO: Get real reason for parse failure here. Might we want to retry?
LL_WARNS(LOG_MESH) << "Unable to parse mesh header. ID: " << mesh_id
- << ", Unknown reason. Not retrying."
+ << ", Size: " << data_size
+ << ", Reason: " << res << " Not retrying."
<< LL_ENDL;
// Can't get the header so none of the LODs will be available
@@ -3174,7 +3219,6 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
header = iter->second;
}
- gMeshRepo.mThread->mHeaderMutex->unlock();
if (header_bytes > 0
&& !header.has("404")
@@ -3195,7 +3239,10 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
- S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+ // Do not unlock mutex untill we are done with LLSD.
+ // LLSD is smart and can work like smart pointer, is not thread safe.
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
S32 bytes = lod_bytes + header_bytes;
@@ -3231,6 +3278,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
@@ -3431,7 +3480,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3
{
if ((!MESH_PHYS_SHAPE_PROCESS_FAILED)
&& ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong
- && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size))
+ && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size) == MESH_OK)
{
// good fetch from sim, write to VFS for caching
LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE);
@@ -3471,6 +3520,11 @@ void LLMeshRepository::init()
LLConvexDecomposition::getInstance()->initSystem();
+ if (!LLConvexDecomposition::isFunctional())
+ {
+ LL_INFOS(LOG_MESH) << "Using STUB for LLConvexDecomposition" << LL_ENDL;
+ }
+
mDecompThread = new LLPhysicsDecomp();
mDecompThread->start();
@@ -4095,42 +4149,42 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
{
- LLSD mesh = mThread->getMeshHeader(mesh_id);
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
- {
- return true;
- }
-
- LLModel::Decomposition* decomp = getDecomposition(mesh_id);
- if (decomp && !decomp->mHull.empty())
- {
- return true;
- }
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
- return false;
-}
+ if (mThread->hasPhysicsShapeInHeader(mesh_id))
+ {
+ return true;
+ }
-LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
-{
- LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
+ LLModel::Decomposition* decomp = getDecomposition(mesh_id);
+ if (decomp && !decomp->mHull.empty())
+ {
+ return true;
+ }
- return mThread->getMeshHeader(mesh_id);
+ return false;
}
-LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
- static LLSD dummy_ret;
- if (mesh_id.notNull())
- {
- LLMutexLock lock(mHeaderMutex);
- mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
- {
- return iter->second;
- }
- }
+ LLMutexLock lock(mHeaderMutex);
+ if (mMeshHeaderSize[mesh_id] > 0)
+ {
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end())
+ {
+ LLSD &mesh = iter->second;
+ if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ {
+ return true;
+ }
+ }
+ }
- return dummy_ret;
+ return false;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index bba0c9f2cb..81e49cb1d8 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -57,6 +57,8 @@ typedef enum e_mesh_processing_result_enum
MESH_NO_DATA = 1,
MESH_OUT_OF_MEMORY,
MESH_HTTP_REQUEST_FAILED,
+ MESH_PARSE_FAILURE,
+ MESH_INVALID,
MESH_UNKNOWN
} EMeshProcessingResult;
@@ -336,12 +338,12 @@ public:
bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true);
bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true);
- bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
+ EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size);
bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
- bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
- LLSD& getMeshHeader(const LLUUID& mesh_id);
+ EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
+ bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -593,9 +595,6 @@ public:
bool meshUploadEnabled();
bool meshRezEnabled();
-
-
- LLSD& getMeshHeader(const LLUUID& mesh_id);
void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
new file mode 100644
index 0000000000..a9e80ab5da
--- /dev/null
+++ b/indra/newview/llmodelpreview.cpp
@@ -0,0 +1,3570 @@
+/**
+ * @file llmodelpreview.cpp
+ * @brief LLModelPreview class implementation
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmodelpreview.h"
+
+#include "llmodelloader.h"
+#include "lldaeloader.h"
+#include "llfloatermodelpreview.h"
+
+#include "llagent.h"
+#include "llanimationstates.h"
+#include "llcallbacklist.h"
+#include "lldatapacker.h"
+#include "lldrawable.h"
+#include "llface.h"
+#include "lliconctrl.h"
+#include "llmatrix4a.h"
+#include "llmeshrepository.h"
+#include "llrender.h"
+#include "llsdutil_math.h"
+#include "llskinningutil.h"
+#include "llstring.h"
+#include "llsdserialize.h"
+#include "lltoolmgr.h"
+#include "llui.h"
+#include "llvector4a.h"
+#include "llviewercamera.h"
+#include "llviewercontrol.h"
+#include "llviewerobjectlist.h"
+#include "llviewernetwork.h"
+#include "llviewershadermgr.h"
+#include "llviewertexteditor.h"
+#include "llviewertexturelist.h"
+#include "llvoavatar.h"
+#include "pipeline.h"
+
+// ui controls (from floater)
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llspinctrl.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+
+#include "glod/glod.h"
+#include <boost/algorithm/string.hpp>
+
+bool LLModelPreview::sIgnoreLoadedCallback = false;
+
+// Extra configurability, to be exposed later in xml (LLModelPreview probably
+// should become UI control at some point or get split into preview control)
+static const LLColor4 PREVIEW_CANVAS_COL(0.169f, 0.169f, 0.169f, 1.f);
+static const LLColor4 PREVIEW_EDGE_COL(0.4f, 0.4f, 0.4f, 1.0);
+static const LLColor4 PREVIEW_BASE_COL(1.f, 1.f, 1.f, 1.f);
+static const LLColor3 PREVIEW_BRIGHTNESS(0.9f, 0.9f, 0.9f);
+static const F32 PREVIEW_EDGE_WIDTH(1.f);
+static const LLColor4 PREVIEW_PSYH_EDGE_COL(0.f, 0.25f, 0.5f, 0.25f);
+static const LLColor4 PREVIEW_PSYH_FILL_COL(0.f, 0.5f, 1.0f, 0.5f);
+static const F32 PREVIEW_PSYH_EDGE_WIDTH(1.f);
+static const LLColor4 PREVIEW_DEG_EDGE_COL(1.f, 0.f, 0.f, 1.f);
+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);
+
+const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
+
+BOOL stop_gloderror()
+{
+ GLuint error = glodGetError();
+
+ if (error != GLOD_NO_ERROR)
+ {
+ LL_WARNS() << "GLOD error detected, cannot generate LOD: " << std::hex << error << LL_ENDL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& material)
+{
+ LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(material.getDiffuseMap(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_PREVIEW);
+
+ if (texture)
+ {
+ if (texture->getDiscardLevel() > -1)
+ {
+ gGL.getTexUnit(0)->bind(texture, true);
+ return texture;
+ }
+ }
+
+ return NULL;
+}
+
+std::string stripSuffix(std::string name)
+{
+ if ((name.find("_LOD") != -1) || (name.find("_PHYS") != -1))
+ {
+ return name.substr(0, name.rfind('_'));
+ }
+ return name;
+}
+
+std::string getLodSuffix(S32 lod)
+{
+ std::string suffix;
+ switch (lod)
+ {
+ case LLModel::LOD_IMPOSTOR: suffix = "_LOD0"; break;
+ case LLModel::LOD_LOW: suffix = "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: suffix = "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: suffix = "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+ return suffix;
+}
+
+void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LLModel*& baseModelOut, LLMatrix4& matOut)
+{
+ LLModelLoader::scene::iterator base_iter = scene.begin();
+ bool found = false;
+ while (!found && (base_iter != scene.end()))
+ {
+ matOut = base_iter->first;
+
+ LLModelLoader::model_instance_list::iterator base_instance_iter = base_iter->second.begin();
+ while (!found && (base_instance_iter != base_iter->second.end()))
+ {
+ LLModelInstance& base_instance = *base_instance_iter++;
+ LLModel* base_model = base_instance.mModel;
+
+ if (base_model && (base_model->mLabel == name_to_match))
+ {
+ baseModelOut = base_model;
+ return;
+ }
+ }
+ base_iter++;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLModelPreview
+//-----------------------------------------------------------------------------
+
+LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
+ : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex()
+ , mLodsQuery()
+ , mLodsWithParsingError()
+ , mPelvisZOffset(0.0f)
+ , mLegacyRigFlags(U32_MAX)
+ , mRigValidJointUpload(false)
+ , mPhysicsSearchLOD(LLModel::LOD_PHYSICS)
+ , mResetJoints(false)
+ , mModelNoErrors(true)
+ , mLastJointUpdate(false)
+ , mFirstSkinUpdate(true)
+ , mHasDegenerate(false)
+ , mImporterDebug(LLCachedControl<bool>(gSavedSettings, "ImporterDebug", false))
+{
+ mNeedsUpdate = TRUE;
+ mCameraDistance = 0.f;
+ mCameraYaw = 0.f;
+ mCameraPitch = 0.f;
+ mCameraZoom = 1.f;
+ mTextureName = 0;
+ mPreviewLOD = 0;
+ mModelLoader = NULL;
+ mMaxTriangleLimit = 0;
+ mDirty = false;
+ mGenLOD = false;
+ mLoading = false;
+ mLookUpLodFiles = false;
+ mLoadState = LLModelLoader::STARTING;
+ mGroup = 0;
+ mLODFrozen = false;
+ mBuildShareTolerance = 0.f;
+ mBuildQueueMode = GLOD_QUEUE_GREEDY;
+ mBuildBorderMode = GLOD_BORDER_UNLOCK;
+ mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE;
+
+ for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
+ {
+ mRequestedTriangleCount[i] = 0;
+ mRequestedCreaseAngle[i] = -1.f;
+ mRequestedLoDMode[i] = 0;
+ mRequestedErrorThreshold[i] = 0.f;
+ mRequestedBuildOperator[i] = 0;
+ mRequestedQueueMode[i] = 0;
+ mRequestedBorderMode[i] = 0;
+ mRequestedShareTolerance[i] = 0.f;
+ }
+
+ mViewOption["show_textures"] = false;
+
+ mFMP = fmp;
+
+ mHasPivot = false;
+ mModelPivot = LLVector3(0.0f, 0.0f, 0.0f);
+
+ glodInit();
+
+ createPreviewAvatar();
+}
+
+LLModelPreview::~LLModelPreview()
+{
+ // glod apparently has internal mem alignment issues that are angering
+ // the heap-check code in windows, these should be hunted down in that
+ // TP code, if possible
+ //
+ // kernel32.dll!HeapFree() + 0x14 bytes
+ // msvcr100.dll!free(void * pBlock) Line 51 C
+ // glod.dll!glodGetGroupParameteriv() + 0x119 bytes
+ // glod.dll!glodShutdown() + 0x77 bytes
+ //
+ //glodShutdown();
+ if (mModelLoader)
+ {
+ mModelLoader->shutdown();
+ }
+
+ if (mPreviewAvatar)
+ {
+ mPreviewAvatar->markDead();
+ mPreviewAvatar = NULL;
+ }
+}
+
+U32 LLModelPreview::calcResourceCost()
+{
+ assert_main_thread();
+
+ rebuildUploadData();
+
+ //Upload skin is selected BUT check to see if the joints coming in from the asset were malformed.
+ if (mFMP && mFMP->childGetValue("upload_skin").asBoolean())
+ {
+ bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean();
+ if (uploadingJointPositions && !isRigValidForJointPositionUpload())
+ {
+ mFMP->childDisable("ok_btn");
+ }
+ }
+
+ std::set<LLModel*> accounted;
+ U32 num_points = 0;
+ U32 num_hulls = 0;
+
+ F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f;
+ mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f;
+
+ if (mFMP && mFMP->childGetValue("upload_joints").asBoolean())
+ {
+ // FIXME if preview avatar ever gets reused, this fake mesh ID stuff will fail.
+ // see also call to addAttachmentPosOverride.
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ getPreviewAvatar()->addPelvisFixup(mPelvisZOffset, fake_mesh_id);
+ }
+
+ F32 streaming_cost = 0.f;
+ F32 physics_cost = 0.f;
+ for (U32 i = 0; i < mUploadData.size(); ++i)
+ {
+ LLModelInstance& instance = mUploadData[i];
+
+ if (accounted.find(instance.mModel) == accounted.end())
+ {
+ accounted.insert(instance.mModel);
+
+ LLModel::Decomposition& decomp =
+ instance.mLOD[LLModel::LOD_PHYSICS] ?
+ instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
+ instance.mModel->mPhysics;
+
+ //update instance skin info for each lods pelvisZoffset
+ for (int j = 0; j<LLModel::NUM_LODS; ++j)
+ {
+ if (instance.mLOD[j])
+ {
+ instance.mLOD[j]->mSkinInfo.mPelvisOffset = mPelvisZOffset;
+ }
+ }
+
+ std::stringstream ostr;
+ LLSD ret = LLModel::writeModel(ostr,
+ instance.mLOD[4],
+ instance.mLOD[3],
+ instance.mLOD[2],
+ instance.mLOD[1],
+ instance.mLOD[0],
+ decomp,
+ mFMP->childGetValue("upload_skin").asBoolean(),
+ mFMP->childGetValue("upload_joints").asBoolean(),
+ mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(),
+ TRUE,
+ FALSE,
+ instance.mModel->mSubmodelID);
+
+ num_hulls += decomp.mHull.size();
+ for (U32 i = 0; i < decomp.mHull.size(); ++i)
+ {
+ num_points += decomp.mHull[i].size();
+ }
+
+ //calculate streaming cost
+ LLMatrix4 transformation = instance.mTransform;
+
+ LLVector3 position = LLVector3(0, 0, 0) * transformation;
+
+ LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position;
+ LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position;
+ LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position;
+ F32 x_length = x_transformed.normalize();
+ F32 y_length = y_transformed.normalize();
+ F32 z_length = z_transformed.normalize();
+ LLVector3 scale = LLVector3(x_length, y_length, z_length);
+
+ F32 radius = scale.length()*0.5f*debug_scale;
+
+ LLMeshCostData costs;
+ if (gMeshRepo.getCostData(ret, costs))
+ {
+ streaming_cost += costs.getRadiusBasedStreamingCost(radius);
+ }
+ }
+ }
+
+ F32 scale = mFMP ? mFMP->childGetValue("import_scale").asReal()*2.f : 2.f;
+
+ mDetailsSignal(mPreviewScale[0] * scale, mPreviewScale[1] * scale, mPreviewScale[2] * scale, streaming_cost, physics_cost);
+
+ updateStatusMessages();
+
+ return (U32)streaming_cost;
+}
+
+void LLModelPreview::rebuildUploadData()
+{
+ assert_main_thread();
+
+ mUploadData.clear();
+ mTextureSet.clear();
+
+ //fill uploaddata instance vectors from scene data
+
+ std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString();
+
+ LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
+
+ F32 scale = scale_spinner->getValue().asReal();
+
+ LLMatrix4 scale_mat;
+ scale_mat.initScale(LLVector3(scale, scale, scale));
+
+ F32 max_scale = 0.f;
+
+ BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ U32 load_state = 0;
+
+ for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter)
+ { //for each transform in scene
+ LLMatrix4 mat = iter->first;
+
+ // compute position
+ LLVector3 position = LLVector3(0, 0, 0) * mat;
+
+ // compute scale
+ LLVector3 x_transformed = LLVector3(1, 0, 0) * mat - position;
+ LLVector3 y_transformed = LLVector3(0, 1, 0) * mat - position;
+ LLVector3 z_transformed = LLVector3(0, 0, 1) * mat - position;
+ F32 x_length = x_transformed.normalize();
+ F32 y_length = y_transformed.normalize();
+ F32 z_length = z_transformed.normalize();
+
+ max_scale = llmax(llmax(llmax(max_scale, x_length), y_length), z_length);
+
+ mat *= scale_mat;
+
+ for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end();)
+ { //for each instance with said transform applied
+ LLModelInstance instance = *model_iter++;
+
+ LLModel* base_model = instance.mModel;
+
+ if (base_model && !requested_name.empty())
+ {
+ base_model->mRequestedLabel = requested_name;
+ }
+
+ for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--)
+ {
+ LLModel* lod_model = NULL;
+ if (!legacyMatching)
+ {
+ // Fill LOD slots by finding matching meshes by label with name extensions
+ // in the appropriate scene for each LOD. This fixes all kinds of issues
+ // where the indexed method below fails in spectacular fashion.
+ // If you don't take the time to name your LOD and PHYS meshes
+ // with the name of their corresponding mesh in the HIGH LOD,
+ // then the indexed method will be attempted below.
+
+ LLMatrix4 transform;
+
+ std::string name_to_match = instance.mLabel;
+ llassert(!name_to_match.empty());
+
+ int extensionLOD;
+ if (i != LLModel::LOD_PHYSICS || mModel[LLModel::LOD_PHYSICS].empty())
+ {
+ extensionLOD = i;
+ }
+ else
+ {
+ //Physics can be inherited from other LODs or loaded, so we need to adjust what extension we are searching for
+ extensionLOD = mPhysicsSearchLOD;
+ }
+
+ std::string toAdd = getLodSuffix(extensionLOD);
+
+ if (name_to_match.find(toAdd) == -1)
+ {
+ name_to_match += toAdd;
+ }
+
+ FindModel(mScene[i], name_to_match, lod_model, transform);
+
+ if (!lod_model && i != LLModel::LOD_PHYSICS)
+ {
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Search of" << name_to_match;
+ out << " in LOD" << i;
+ out << " list failed. Searching for alternative among LOD lists.";
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+
+ int searchLOD = (i > LLModel::LOD_HIGH) ? LLModel::LOD_HIGH : i;
+ while ((searchLOD <= LLModel::LOD_HIGH) && !lod_model)
+ {
+ std::string name_to_match = instance.mLabel;
+ llassert(!name_to_match.empty());
+
+ std::string toAdd = getLodSuffix(searchLOD);
+
+ if (name_to_match.find(toAdd) == -1)
+ {
+ name_to_match += toAdd;
+ }
+
+ // See if we can find an appropriately named model in LOD 'searchLOD'
+ //
+ FindModel(mScene[searchLOD], name_to_match, lod_model, transform);
+ searchLOD++;
+ }
+ }
+ }
+ else
+ {
+ // Use old method of index-based association
+ U32 idx = 0;
+ for (idx = 0; idx < mBaseModel.size(); ++idx)
+ {
+ // find reference instance for this model
+ if (mBaseModel[idx] == base_model)
+ {
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Attempting to use model index " << idx;
+ out << " for LOD" << i;
+ out << " of " << instance.mLabel;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ break;
+ }
+ }
+
+ // If the model list for the current LOD includes that index...
+ //
+ if (mModel[i].size() > idx)
+ {
+ // Assign that index from the model list for our LOD as the LOD model for this instance
+ //
+ lod_model = mModel[i][idx];
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Indexed match of model index " << idx << " at LOD " << i << " to model named " << lod_model->mLabel;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ }
+ else if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "List of models does not include index " << idx;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ }
+
+ if (lod_model)
+ {
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ if (i == LLModel::LOD_PHYSICS)
+ {
+ out << "Assigning collision for " << instance.mLabel << " to match " << lod_model->mLabel;
+ }
+ else
+ {
+ out << "Assigning LOD" << i << " for " << instance.mLabel << " to found match " << lod_model->mLabel;
+ }
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ instance.mLOD[i] = lod_model;
+ }
+ else
+ {
+ if (i < LLModel::LOD_HIGH && !lodsReady())
+ {
+ // assign a placeholder from previous LOD until lod generation is complete.
+ // Note: we might need to assign it regardless of conditions like named search does, to prevent crashes.
+ instance.mLOD[i] = instance.mLOD[i + 1];
+ }
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "List of models does not include " << instance.mLabel;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ }
+ }
+
+ LLModel* high_lod_model = instance.mLOD[LLModel::LOD_HIGH];
+ if (!high_lod_model)
+ {
+ LLFloaterModelPreview::addStringToLog("Model " + instance.mLabel + " has no High Lod (LOD3).", true);
+ load_state = LLModelLoader::ERROR_MATERIALS;
+ mFMP->childDisable("calculate_btn");
+ }
+ else
+ {
+ for (U32 i = 0; i < LLModel::NUM_LODS - 1; i++)
+ {
+ int refFaceCnt = 0;
+ int modelFaceCnt = 0;
+ llassert(instance.mLOD[i]);
+ if (instance.mLOD[i] && !instance.mLOD[i]->matchMaterialOrder(high_lod_model, refFaceCnt, modelFaceCnt))
+ {
+ LLFloaterModelPreview::addStringToLog("Model " + instance.mLabel + " has mismatching materials between lods." , true);
+ load_state = LLModelLoader::ERROR_MATERIALS;
+ mFMP->childDisable("calculate_btn");
+ }
+ }
+ LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)mFMP;
+ bool upload_skinweights = fmp && fmp->childGetValue("upload_skin").asBoolean();
+ if (upload_skinweights && high_lod_model->mSkinInfo.mJointNames.size() > 0)
+ {
+ LLQuaternion bind_rot = LLSkinningUtil::getUnscaledQuaternion(high_lod_model->mSkinInfo.mBindShapeMatrix);
+ LLQuaternion identity;
+ if (!bind_rot.isEqualEps(identity, 0.01))
+ {
+ // Bind shape matrix is not in standard X-forward orientation.
+ // Might be good idea to only show this once. It can be spammy.
+ std::ostringstream out;
+ out << "non-identity bind shape rot. mat is ";
+ out << high_lod_model->mSkinInfo.mBindShapeMatrix;
+ out << " bind_rot ";
+ out << bind_rot;
+ LL_WARNS() << out.str() << LL_ENDL;
+
+ LLFloaterModelPreview::addStringToLog(out, getLoadState() != LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION);
+ load_state = LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION;
+ }
+ }
+ }
+ instance.mTransform = mat;
+ mUploadData.push_back(instance);
+ }
+ }
+
+ for (U32 lod = 0; lod < LLModel::NUM_LODS - 1; lod++)
+ {
+ // Search for models that are not included into upload data
+ // If we found any, that means something we loaded is not a sub-model.
+ for (U32 model_ind = 0; model_ind < mModel[lod].size(); ++model_ind)
+ {
+ bool found_model = false;
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+ if (instance.mLOD[lod] == mModel[lod][model_ind])
+ {
+ found_model = true;
+ break;
+ }
+ }
+ if (!found_model && mModel[lod][model_ind] && !mModel[lod][model_ind]->mSubmodelID)
+ {
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Model " << mModel[lod][model_ind]->mLabel << " was not used - mismatching lod models.";
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, true);
+ }
+ load_state = LLModelLoader::ERROR_MATERIALS;
+ mFMP->childDisable("calculate_btn");
+ }
+ }
+ }
+
+ // Update state for notifications
+ if (load_state > 0)
+ {
+ // encountered issues
+ setLoadState(load_state);
+ }
+ else if (getLoadState() == LLModelLoader::ERROR_MATERIALS
+ || getLoadState() == LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION)
+ {
+ // This is only valid for these two error types because they are
+ // only used inside rebuildUploadData() and updateStatusMessages()
+ // updateStatusMessages() is called after rebuildUploadData()
+ setLoadState(LLModelLoader::DONE);
+ }
+
+ F32 max_import_scale = (DEFAULT_MAX_PRIM_SCALE - 0.1f) / max_scale;
+
+ F32 max_axis = llmax(mPreviewScale.mV[0], mPreviewScale.mV[1]);
+ max_axis = llmax(max_axis, mPreviewScale.mV[2]);
+ max_axis *= 2.f;
+
+ //clamp scale so that total imported model bounding box is smaller than 240m on a side
+ max_import_scale = llmin(max_import_scale, 240.f / max_axis);
+
+ scale_spinner->setMaxValue(max_import_scale);
+
+ if (max_import_scale < scale)
+ {
+ scale_spinner->setValue(max_import_scale);
+ }
+
+}
+
+void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)
+{
+ if (!mLODFile[LLModel::LOD_HIGH].empty())
+ {
+ std::string filename = mLODFile[LLModel::LOD_HIGH];
+ std::string slm_filename;
+
+ if (LLModelLoader::getSLMFilename(filename, slm_filename))
+ {
+ saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position);
+ }
+ }
+}
+
+void LLModelPreview::saveUploadData(const std::string& filename,
+ bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)
+{
+
+ std::set<LLPointer<LLModel> > meshes;
+ std::map<LLModel*, std::string> mesh_binary;
+
+ LLModel::hull empty_hull;
+
+ LLSD data;
+
+ data["version"] = SLM_SUPPORTED_VERSION;
+ if (!mBaseModel.empty())
+ {
+ data["name"] = mBaseModel[0]->getName();
+ }
+
+ S32 mesh_id = 0;
+
+ //build list of unique models and initialize local id
+ for (U32 i = 0; i < mUploadData.size(); ++i)
+ {
+ LLModelInstance& instance = mUploadData[i];
+
+ if (meshes.find(instance.mModel) == meshes.end())
+ {
+ instance.mModel->mLocalID = mesh_id++;
+ meshes.insert(instance.mModel);
+
+ std::stringstream str;
+ LLModel::Decomposition& decomp =
+ instance.mLOD[LLModel::LOD_PHYSICS].notNull() ?
+ instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics :
+ instance.mModel->mPhysics;
+
+ LLModel::writeModel(str,
+ instance.mLOD[LLModel::LOD_PHYSICS],
+ instance.mLOD[LLModel::LOD_HIGH],
+ instance.mLOD[LLModel::LOD_MEDIUM],
+ instance.mLOD[LLModel::LOD_LOW],
+ instance.mLOD[LLModel::LOD_IMPOSTOR],
+ decomp,
+ save_skinweights,
+ save_joint_positions,
+ lock_scale_if_joint_position,
+ FALSE, TRUE, instance.mModel->mSubmodelID);
+
+ data["mesh"][instance.mModel->mLocalID] = str.str();
+ }
+
+ data["instance"][i] = instance.asLLSD();
+ }
+
+ llofstream out(filename.c_str(), std::ios_base::out | std::ios_base::binary);
+ LLSDSerialize::toBinary(data, out);
+ out.flush();
+ out.close();
+}
+
+void LLModelPreview::clearModel(S32 lod)
+{
+ if (lod < 0 || lod > LLModel::LOD_PHYSICS)
+ {
+ return;
+ }
+
+ mVertexBuffer[lod].clear();
+ mModel[lod].clear();
+ mScene[lod].clear();
+}
+
+void LLModelPreview::getJointAliases(JointMap& joint_map)
+{
+ // Get all standard skeleton joints from the preview avatar.
+ LLVOAvatar *av = getPreviewAvatar();
+
+ //Joint names and aliases come from avatar_skeleton.xml
+
+ joint_map = av->getJointAliases();
+
+ std::vector<std::string> cv_names, attach_names;
+ av->getSortedJointNames(1, cv_names);
+ av->getSortedJointNames(2, attach_names);
+ for (std::vector<std::string>::iterator it = cv_names.begin(); it != cv_names.end(); ++it)
+ {
+ joint_map[*it] = *it;
+ }
+ for (std::vector<std::string>::iterator it = attach_names.begin(); it != attach_names.end(); ++it)
+ {
+ joint_map[*it] = *it;
+ }
+}
+
+void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm)
+{
+ assert_main_thread();
+
+ LLMutexLock lock(this);
+
+ if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::NUM_LODS - 1)
+ {
+ std::ostringstream out;
+ out << "Invalid level of detail: ";
+ out << lod;
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, true);
+ assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS);
+ return;
+ }
+
+ // This triggers if you bring up the file picker and then hit CANCEL.
+ // Just use the previous model (if any) and ignore that you brought up
+ // the file picker.
+
+ if (filename.empty())
+ {
+ if (mBaseModel.empty())
+ {
+ // this is the initial file picking. Close the whole floater
+ // if we don't have a base model to show for high LOD.
+ mFMP->closeFloater(false);
+ }
+ mLoading = false;
+ return;
+ }
+
+ if (mModelLoader)
+ {
+ LL_WARNS() << "Incompleted model load operation pending." << LL_ENDL;
+ return;
+ }
+
+ mLODFile[lod] = filename;
+
+ if (lod == LLModel::LOD_HIGH)
+ {
+ clearGLODGroup();
+ }
+
+ 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"));
+
+ if (force_disable_slm)
+ {
+ mModelLoader->mTrySLM = false;
+ }
+ else
+ {
+ // For MAINT-6647, we have set force_disable_slm to true,
+ // which means this code path will never be taken. Trying to
+ // re-use SLM files has never worked properly; in particular,
+ // it tends to force the UI into strange checkbox options
+ // which cannot be altered.
+
+ //only try to load from slm if viewer is configured to do so and this is the
+ //initial model load (not an LoD or physics shape)
+ mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty();
+ }
+ mModelLoader->start();
+
+ mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file"));
+
+ setPreviewLOD(lod);
+
+ if (getLoadState() >= LLModelLoader::ERROR_PARSING)
+ {
+ mFMP->childDisable("ok_btn");
+ mFMP->childDisable("calculate_btn");
+ }
+
+ if (lod == mPreviewLOD)
+ {
+ mFMP->childSetValue("lod_file_" + lod_name[lod], mLODFile[lod]);
+ }
+ else if (lod == LLModel::LOD_PHYSICS)
+ {
+ mFMP->childSetValue("physics_file", mLODFile[lod]);
+ }
+
+ mFMP->openFloater();
+}
+
+void LLModelPreview::setPhysicsFromLOD(S32 lod)
+{
+ assert_main_thread();
+
+ if (lod >= 0 && lod <= 3)
+ {
+ mPhysicsSearchLOD = lod;
+ mModel[LLModel::LOD_PHYSICS] = mModel[lod];
+ mScene[LLModel::LOD_PHYSICS] = mScene[lod];
+ mLODFile[LLModel::LOD_PHYSICS].clear();
+ mFMP->childSetValue("physics_file", mLODFile[LLModel::LOD_PHYSICS]);
+ mVertexBuffer[LLModel::LOD_PHYSICS].clear();
+ rebuildUploadData();
+ refresh();
+ updateStatusMessages();
+ }
+}
+
+void LLModelPreview::clearIncompatible(S32 lod)
+{
+ //Don't discard models if specified model is the physic rep
+ if (lod == LLModel::LOD_PHYSICS)
+ {
+ return;
+ }
+
+ // 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]);
+ for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
+ { //clear out any entries that aren't compatible with this model
+ if (i != lod)
+ {
+ if (countRootModels(mModel[i]) != lod_size)
+ {
+ mModel[i].clear();
+ mScene[i].clear();
+ mVertexBuffer[i].clear();
+
+ if (i == LLModel::LOD_HIGH)
+ {
+ mBaseModel = mModel[lod];
+ clearGLODGroup();
+ mBaseScene = mScene[lod];
+ mVertexBuffer[5].clear();
+ }
+ }
+ }
+ }
+}
+
+void LLModelPreview::clearGLODGroup()
+{
+ if (mGroup)
+ {
+ for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter)
+ {
+ glodDeleteObject(iter->second);
+ stop_gloderror();
+ }
+ mObject.clear();
+
+ glodDeleteGroup(mGroup);
+ stop_gloderror();
+ mGroup = 0;
+ }
+}
+
+void LLModelPreview::loadModelCallback(S32 loaded_lod)
+{
+ assert_main_thread();
+
+ LLMutexLock lock(this);
+ if (!mModelLoader)
+ {
+ mLoading = false;
+ return;
+ }
+ if (getLoadState() >= LLModelLoader::ERROR_PARSING)
+ {
+ mLoading = false;
+ mModelLoader = NULL;
+ mLodsWithParsingError.push_back(loaded_lod);
+ return;
+ }
+
+ mLodsWithParsingError.erase(std::remove(mLodsWithParsingError.begin(), mLodsWithParsingError.end(), loaded_lod), mLodsWithParsingError.end());
+ if (mLodsWithParsingError.empty())
+ {
+ mFMP->childEnable("calculate_btn");
+ }
+
+ // Copy determinations about rig so UI will reflect them
+ //
+ setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload());
+ setLegacyRigFlags(mModelLoader->getLegacyRigFlags());
+
+ mModelLoader->loadTextures();
+
+ if (loaded_lod == -1)
+ { //populate all LoDs from model loader scene
+ mBaseModel.clear();
+ mBaseScene.clear();
+
+ bool skin_weights = false;
+ bool joint_overrides = false;
+ bool lock_scale_if_joint_position = false;
+
+ for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)
+ { //for each LoD
+
+ //clear scene and model info
+ mScene[lod].clear();
+ mModel[lod].clear();
+ mVertexBuffer[lod].clear();
+
+ if (mModelLoader->mScene.begin()->second[0].mLOD[lod].notNull())
+ { //if this LoD exists in the loaded scene
+
+ //copy scene to current LoD
+ mScene[lod] = mModelLoader->mScene;
+
+ //touch up copied scene to look like current LoD
+ for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter)
+ {
+ LLModelLoader::model_instance_list& list = iter->second;
+
+ for (LLModelLoader::model_instance_list::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter)
+ {
+ //override displayed model with current LoD
+ list_iter->mModel = list_iter->mLOD[lod];
+
+ if (!list_iter->mModel)
+ {
+ continue;
+ }
+
+ //add current model to current LoD's model list (LLModel::mLocalID makes a good vector index)
+ S32 idx = list_iter->mModel->mLocalID;
+
+ if (mModel[lod].size() <= idx)
+ { //stretch model list to fit model at given index
+ mModel[lod].resize(idx + 1);
+ }
+
+ mModel[lod][idx] = list_iter->mModel;
+ if (!list_iter->mModel->mSkinWeights.empty())
+ {
+ skin_weights = true;
+
+ if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty())
+ {
+ joint_overrides = true;
+ }
+ if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition)
+ {
+ lock_scale_if_joint_position = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mFMP)
+ {
+ LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)mFMP;
+
+ if (skin_weights)
+ { //enable uploading/previewing of skin weights if present in .slm file
+ fmp->enableViewOption("show_skin_weight");
+ mViewOption["show_skin_weight"] = true;
+ fmp->childSetValue("upload_skin", true);
+ }
+
+ if (joint_overrides)
+ {
+ fmp->enableViewOption("show_joint_overrides");
+ mViewOption["show_joint_overrides"] = true;
+ fmp->enableViewOption("show_joint_positions");
+ mViewOption["show_joint_positions"] = true;
+ fmp->childSetValue("upload_joints", true);
+ }
+ else
+ {
+ fmp->clearAvatarTab();
+ }
+
+ if (lock_scale_if_joint_position)
+ {
+ fmp->enableViewOption("lock_scale_if_joint_position");
+ mViewOption["lock_scale_if_joint_position"] = true;
+ fmp->childSetValue("lock_scale_if_joint_position", true);
+ }
+ }
+
+ //copy high lod to base scene for LoD generation
+ mBaseScene = mScene[LLModel::LOD_HIGH];
+ mBaseModel = mModel[LLModel::LOD_HIGH];
+
+ mDirty = true;
+ resetPreviewTarget();
+ }
+ else
+ { //only replace given LoD
+ mModel[loaded_lod] = mModelLoader->mModelList;
+ mScene[loaded_lod] = mModelLoader->mScene;
+ mVertexBuffer[loaded_lod].clear();
+
+ setPreviewLOD(loaded_lod);
+
+ if (loaded_lod == LLModel::LOD_HIGH)
+ { //save a copy of the highest LOD for automatic LOD manipulation
+ if (mBaseModel.empty())
+ { //first time we've loaded a model, auto-gen LoD
+ mGenLOD = true;
+ }
+
+ mBaseModel = mModel[loaded_lod];
+ clearGLODGroup();
+
+ mBaseScene = mScene[loaded_lod];
+ mVertexBuffer[5].clear();
+ }
+ else
+ {
+ BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ if (!legacyMatching)
+ {
+ if (!mBaseModel.empty())
+ {
+ BOOL name_based = FALSE;
+ BOOL has_submodels = FALSE;
+ for (U32 idx = 0; idx < mBaseModel.size(); ++idx)
+ {
+ if (mBaseModel[idx]->mSubmodelID)
+ { // don't do index-based renaming when the base model has submodels
+ has_submodels = TRUE;
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "High LOD has submodels";
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+ break;
+ }
+ }
+
+ for (U32 idx = 0; idx < mModel[loaded_lod].size(); ++idx)
+ {
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ LLModel* found_model = NULL;
+ LLMatrix4 transform;
+ FindModel(mBaseScene, loaded_name, found_model, transform);
+ if (found_model)
+ { // don't rename correctly named models (even if they are placed in a wrong order)
+ name_based = TRUE;
+ }
+
+ if (mModel[loaded_lod][idx]->mSubmodelID)
+ { // don't rename the models when loaded LOD model has submodels
+ has_submodels = TRUE;
+ }
+ }
+
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Loaded LOD " << loaded_lod << ": correct names" << (name_based ? "" : "NOT ") << "found; submodels " << (has_submodels ? "" : "NOT ") << "found";
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+
+ if (!name_based && !has_submodels)
+ { // replace the name of the model loaded for any non-HIGH LOD to match the others (MAINT-5601)
+ // this actually works like "ImporterLegacyMatching" for this particular LOD
+ for (U32 idx = 0; idx < mModel[loaded_lod].size() && idx < mBaseModel.size(); ++idx)
+ {
+ std::string name = mBaseModel[idx]->mLabel;
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ if (loaded_name != name)
+ {
+ name += getLodSuffix(loaded_lod);
+
+ if (mImporterDebug)
+ {
+ std::ostringstream out;
+ out << "Loded model name " << mModel[loaded_lod][idx]->mLabel;
+ out << " for LOD " << loaded_lod;
+ out << " doesn't match the base model. Renaming to " << name;
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ }
+
+ mModel[loaded_lod][idx]->mLabel = name;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ clearIncompatible(loaded_lod);
+
+ mDirty = true;
+
+ if (loaded_lod == LLModel::LOD_HIGH)
+ {
+ resetPreviewTarget();
+ }
+ }
+
+ mLoading = false;
+ if (mFMP)
+ {
+ if (!mBaseModel.empty())
+ {
+ const std::string& model_name = mBaseModel[0]->getName();
+ LLLineEditor* description_form = mFMP->getChild<LLLineEditor>("description_form");
+ if (description_form->getText().empty())
+ {
+ description_form->setText(model_name);
+ }
+ // Add info to log that loading is complete (purpose: separator between loading and other logs)
+ LLSD args;
+ args["MODEL_NAME"] = model_name; // Teoretically shouldn't be empty, but might be better idea to add filename here
+ LLFloaterModelPreview::addStringToLog("ModelLoaded", args, false, loaded_lod);
+ }
+ }
+ refresh();
+
+ mModelLoadedSignal();
+
+ mModelLoader = NULL;
+}
+
+void LLModelPreview::resetPreviewTarget()
+{
+ if (mModelLoader)
+ {
+ mPreviewTarget = (mModelLoader->mExtents[0] + mModelLoader->mExtents[1]) * 0.5f;
+ mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f;
+ }
+
+ setPreviewTarget(mPreviewScale.magVec()*10.f);
+}
+
+void LLModelPreview::generateNormals()
+{
+ assert_main_thread();
+
+ S32 which_lod = mPreviewLOD;
+
+ if (which_lod > 4 || which_lod < 0 ||
+ mModel[which_lod].empty())
+ {
+ return;
+ }
+
+ F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal();
+
+ mRequestedCreaseAngle[which_lod] = angle_cutoff;
+
+ angle_cutoff *= DEG_TO_RAD;
+
+ if (which_lod == 3 && !mBaseModel.empty())
+ {
+ if (mBaseModelFacesCopy.empty())
+ {
+ mBaseModelFacesCopy.reserve(mBaseModel.size());
+ for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it)
+ {
+ v_LLVolumeFace_t faces;
+ (*it)->copyFacesTo(faces);
+ mBaseModelFacesCopy.push_back(faces);
+ }
+ }
+
+ for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it)
+ {
+ (*it)->generateNormals(angle_cutoff);
+ }
+
+ mVertexBuffer[5].clear();
+ }
+
+ bool perform_copy = mModelFacesCopy[which_lod].empty();
+ if (perform_copy) {
+ mModelFacesCopy[which_lod].reserve(mModel[which_lod].size());
+ }
+
+ for (LLModelLoader::model_list::iterator it = mModel[which_lod].begin(), itE = mModel[which_lod].end(); it != itE; ++it)
+ {
+ if (perform_copy)
+ {
+ v_LLVolumeFace_t faces;
+ (*it)->copyFacesTo(faces);
+ mModelFacesCopy[which_lod].push_back(faces);
+ }
+
+ (*it)->generateNormals(angle_cutoff);
+ }
+
+ mVertexBuffer[which_lod].clear();
+ refresh();
+ updateStatusMessages();
+}
+
+void LLModelPreview::restoreNormals()
+{
+ S32 which_lod = mPreviewLOD;
+
+ if (which_lod > 4 || which_lod < 0 ||
+ mModel[which_lod].empty())
+ {
+ return;
+ }
+
+ if (!mBaseModelFacesCopy.empty())
+ {
+ llassert(mBaseModelFacesCopy.size() == mBaseModel.size());
+
+ vv_LLVolumeFace_t::const_iterator itF = mBaseModelFacesCopy.begin();
+ for (LLModelLoader::model_list::iterator it = mBaseModel.begin(), itE = mBaseModel.end(); it != itE; ++it, ++itF)
+ {
+ (*it)->copyFacesFrom((*itF));
+ }
+
+ mBaseModelFacesCopy.clear();
+ }
+
+ if (!mModelFacesCopy[which_lod].empty())
+ {
+ vv_LLVolumeFace_t::const_iterator itF = mModelFacesCopy[which_lod].begin();
+ for (LLModelLoader::model_list::iterator it = mModel[which_lod].begin(), itE = mModel[which_lod].end(); it != itE; ++it, ++itF)
+ {
+ (*it)->copyFacesFrom((*itF));
+ }
+
+ mModelFacesCopy[which_lod].clear();
+ }
+
+ mVertexBuffer[which_lod].clear();
+ refresh();
+ updateStatusMessages();
+}
+
+void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit)
+{
+ // Allow LoD from -1 to LLModel::LOD_PHYSICS
+ if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1)
+ {
+ std::ostringstream out;
+ out << "Invalid level of detail: " << which_lod;
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ assert(which_lod >= -1 && which_lod < LLModel::NUM_LODS);
+ return;
+ }
+
+ if (mBaseModel.empty())
+ {
+ return;
+ }
+
+ LLVertexBuffer::unbind();
+
+ bool no_ff = LLGLSLShader::sNoFixedFunction;
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ LLGLSLShader::sNoFixedFunction = false;
+
+ if (shader)
+ {
+ shader->unbind();
+ }
+
+ stop_gloderror();
+ static U32 cur_name = 1;
+
+ S32 limit = -1;
+
+ U32 triangle_count = 0;
+
+ U32 instanced_triangle_count = 0;
+
+ //get the triangle count for the whole scene
+ for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
+ {
+ LLModel* mdl = instance->mModel;
+ if (mdl)
+ {
+ instanced_triangle_count += mdl->getNumTriangles();
+ }
+ }
+ }
+
+ //get the triangle count for the non-instanced set of models
+ for (U32 i = 0; i < mBaseModel.size(); ++i)
+ {
+ triangle_count += mBaseModel[i]->getNumTriangles();
+ }
+
+ //get ratio of uninstanced triangles to instanced triangles
+ F32 triangle_ratio = (F32)triangle_count / (F32)instanced_triangle_count;
+
+ U32 base_triangle_count = triangle_count;
+
+ U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+
+ U32 lod_mode = 0;
+
+ F32 lod_error_threshold = 0;
+
+ // The LoD should be in range from Lowest to High
+ if (which_lod > -1 && which_lod < NUM_LOD)
+ {
+ LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode_" + lod_name[which_lod]);
+ if (iface)
+ {
+ lod_mode = iface->getFirstSelectedIndex();
+ }
+
+ lod_error_threshold = mFMP->childGetValue("lod_error_threshold_" + lod_name[which_lod]).asReal();
+ }
+
+ if (which_lod != -1)
+ {
+ mRequestedLoDMode[which_lod] = lod_mode;
+ }
+
+ if (lod_mode == 0)
+ {
+ lod_mode = GLOD_TRIANGLE_BUDGET;
+
+ // The LoD should be in range from Lowest to High
+ if (which_lod > -1 && which_lod < NUM_LOD)
+ {
+ limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
+ //convert from "scene wide" to "non-instanced" triangle limit
+ limit = (S32)((F32)limit*triangle_ratio);
+ }
+ }
+ else
+ {
+ lod_mode = GLOD_ERROR_THRESHOLD;
+ }
+
+ bool object_dirty = false;
+
+ if (mGroup == 0)
+ {
+ object_dirty = true;
+ mGroup = cur_name++;
+ glodNewGroup(mGroup);
+ }
+
+ if (object_dirty)
+ {
+ for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
+ { //build GLOD objects for each model in base model list
+ LLModel* mdl = *iter;
+
+ if (mObject[mdl] != 0)
+ {
+ glodDeleteObject(mObject[mdl]);
+ }
+
+ mObject[mdl] = cur_name++;
+
+ glodNewObject(mObject[mdl], mGroup, GLOD_DISCRETE);
+ stop_gloderror();
+
+ if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty())
+ { //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation
+ mVertexBuffer[5].clear();
+ }
+
+ if (mVertexBuffer[5].empty())
+ {
+ genBuffers(5, false);
+ }
+
+ U32 tri_count = 0;
+ for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i)
+ {
+ LLVertexBuffer* buff = mVertexBuffer[5][mdl][i];
+ buff->setBuffer(type_mask & buff->getTypeMask());
+
+ U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();
+ if (num_indices > 2)
+ {
+ glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, (U8*)mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f);
+ }
+ tri_count += num_indices / 3;
+ stop_gloderror();
+ }
+
+ glodBuildObject(mObject[mdl]);
+ stop_gloderror();
+ }
+ }
+
+
+ S32 start = LLModel::LOD_HIGH;
+ S32 end = 0;
+
+ if (which_lod != -1)
+ {
+ start = end = which_lod;
+ }
+
+ mMaxTriangleLimit = base_triangle_count;
+
+ for (S32 lod = start; lod >= end; --lod)
+ {
+ if (which_lod == -1)
+ {
+ if (lod < start)
+ {
+ triangle_count /= decimation;
+ }
+ }
+ else
+ {
+ if (enforce_tri_limit)
+ {
+ triangle_count = limit;
+ }
+ else
+ {
+ for (S32 j = LLModel::LOD_HIGH; j>which_lod; --j)
+ {
+ triangle_count /= decimation;
+ }
+ }
+ }
+
+ mModel[lod].clear();
+ mModel[lod].resize(mBaseModel.size());
+ mVertexBuffer[lod].clear();
+
+ U32 actual_tris = 0;
+ U32 actual_verts = 0;
+ U32 submeshes = 0;
+
+ mRequestedTriangleCount[lod] = (S32)((F32)triangle_count / triangle_ratio);
+ mRequestedErrorThreshold[lod] = lod_error_threshold;
+
+ glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
+ stop_gloderror();
+
+ glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR);
+ stop_gloderror();
+
+ glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold);
+ stop_gloderror();
+
+ if (lod_mode != GLOD_TRIANGLE_BUDGET)
+ {
+ glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, 0);
+ }
+ else
+ {
+ //SH-632: always add 1 to desired amount to avoid decimating below desired amount
+ glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count + 1);
+ }
+
+ stop_gloderror();
+ glodAdaptGroup(mGroup);
+ stop_gloderror();
+
+ for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx)
+ {
+ LLModel* base = mBaseModel[mdl_idx];
+
+ GLint patch_count = 0;
+ glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count);
+ stop_gloderror();
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
+ mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f);
+
+ std::string name = base->mLabel + getLodSuffix(lod);
+
+ mModel[lod][mdl_idx]->mLabel = name;
+ mModel[lod][mdl_idx]->mSubmodelID = base->mSubmodelID;
+
+ GLint* sizes = new GLint[patch_count * 2];
+ glodGetObjectParameteriv(mObject[base], GLOD_PATCH_SIZES, sizes);
+ stop_gloderror();
+
+ GLint* names = new GLint[patch_count];
+ glodGetObjectParameteriv(mObject[base], GLOD_PATCH_NAMES, names);
+ stop_gloderror();
+
+ mModel[lod][mdl_idx]->setNumVolumeFaces(patch_count);
+
+ LLModel* target_model = mModel[lod][mdl_idx];
+
+ for (GLint i = 0; i < patch_count; ++i)
+ {
+ type_mask = mVertexBuffer[5][base][i]->getTypeMask();
+
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
+
+ if (sizes[i * 2 + 1] > 0 && sizes[i * 2] > 0)
+ {
+ if (!buff->allocateBuffer(sizes[i * 2 + 1], sizes[i * 2], true))
+ {
+ // Todo: find a way to stop preview in this case instead of crashing
+ LL_ERRS() << "Failed buffer allocation during preview LOD generation."
+ << " Vertices: " << sizes[i * 2 + 1]
+ << " Indices: " << sizes[i * 2] << LL_ENDL;
+ }
+ buff->setBuffer(type_mask);
+ glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*)buff->getIndicesPointer());
+ stop_gloderror();
+ }
+ else
+ {
+ // This face was eliminated or we failed to allocate buffer,
+ // attempt to create a dummy triangle (one vertex, 3 indices, all 0)
+ buff->allocateBuffer(1, 3, true);
+ memset((U8*)buff->getMappedData(), 0, buff->getSize());
+ memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize());
+ }
+
+ buff->validateRange(0, buff->getNumVerts() - 1, buff->getNumIndices(), 0);
+
+ LLStrider<LLVector3> pos;
+ LLStrider<LLVector3> norm;
+ LLStrider<LLVector2> tc;
+ LLStrider<U16> index;
+
+ buff->getVertexStrider(pos);
+ if (type_mask & LLVertexBuffer::MAP_NORMAL)
+ {
+ buff->getNormalStrider(norm);
+ }
+ if (type_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ buff->getTexCoord0Strider(tc);
+ }
+
+ buff->getIndexStrider(index);
+
+ target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());
+ actual_tris += buff->getNumIndices() / 3;
+ actual_verts += buff->getNumVerts();
+ ++submeshes;
+
+ if (!validate_face(target_model->getVolumeFace(names[i])))
+ {
+ LL_ERRS() << "Invalid face generated during LOD generation." << LL_ENDL;
+ }
+ }
+
+ //blind copy skin weights and just take closest skin weight to point on
+ //decimated mesh for now (auto-generating LODs with skin weights is still a bit
+ //of an open problem).
+ target_model->mPosition = base->mPosition;
+ target_model->mSkinWeights = base->mSkinWeights;
+ target_model->mSkinInfo = base->mSkinInfo;
+ //copy material list
+ target_model->mMaterialList = base->mMaterialList;
+
+ if (!validate_model(target_model))
+ {
+ LL_ERRS() << "Invalid model generated when creating LODs" << LL_ENDL;
+ }
+
+ delete[] sizes;
+ delete[] names;
+ }
+
+ //rebuild scene based on mBaseScene
+ mScene[lod].clear();
+ mScene[lod] = mBaseScene;
+
+ for (U32 i = 0; i < mBaseModel.size(); ++i)
+ {
+ LLModel* mdl = mBaseModel[i];
+ LLModel* target = mModel[lod][i];
+ if (target)
+ {
+ for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter)
+ {
+ for (U32 j = 0; j < iter->second.size(); ++j)
+ {
+ if (iter->second[j].mModel == mdl)
+ {
+ iter->second[j].mModel = target;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ mResourceCost = calcResourceCost();
+
+ LLVertexBuffer::unbind();
+ LLGLSLShader::sNoFixedFunction = no_ff;
+ if (shader)
+ {
+ shader->bind();
+ }
+}
+
+void LLModelPreview::updateStatusMessages()
+{
+ // bit mask values for physics errors. used to prevent overwrite of single line status
+ // TODO: use this to provied multiline status
+ enum PhysicsError
+ {
+ NONE = 0,
+ NOHAVOK = 1,
+ DEGENERATE = 2,
+ TOOMANYHULLS = 4,
+ TOOMANYVERTSINHULL = 8
+ };
+
+ assert_main_thread();
+
+ U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap
+ //triangle/vertex/submesh count for each mesh asset for each lod
+ std::vector<S32> tris[LLModel::NUM_LODS];
+ std::vector<S32> verts[LLModel::NUM_LODS];
+ std::vector<S32> submeshes[LLModel::NUM_LODS];
+
+ //total triangle/vertex/submesh count for each lod
+ S32 total_tris[LLModel::NUM_LODS];
+ S32 total_verts[LLModel::NUM_LODS];
+ S32 total_submeshes[LLModel::NUM_LODS];
+
+ for (U32 i = 0; i < LLModel::NUM_LODS - 1; i++)
+ {
+ total_tris[i] = 0;
+ total_verts[i] = 0;
+ total_submeshes[i] = 0;
+ }
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model_high_lod = instance.mLOD[LLModel::LOD_HIGH];
+ if (!model_high_lod)
+ {
+ setLoadState(LLModelLoader::ERROR_MATERIALS);
+ mFMP->childDisable("calculate_btn");
+ continue;
+ }
+
+ for (U32 i = 0; i < LLModel::NUM_LODS - 1; i++)
+ {
+ LLModel* lod_model = instance.mLOD[i];
+ if (!lod_model)
+ {
+ setLoadState(LLModelLoader::ERROR_MATERIALS);
+ mFMP->childDisable("calculate_btn");
+ }
+ else
+ {
+ //for each model in the lod
+ S32 cur_tris = 0;
+ S32 cur_verts = 0;
+ S32 cur_submeshes = lod_model->getNumVolumeFaces();
+
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = lod_model->getVolumeFace(j);
+ cur_tris += face.mNumIndices / 3;
+ cur_verts += face.mNumVertices;
+ }
+
+ std::string instance_name = instance.mLabel;
+
+ if (mImporterDebug)
+ {
+ // Useful for debugging generalized complaints below about total submeshes which don't have enough
+ // context to address exactly what needs to be fixed to move towards compliance with the rules.
+ //
+ std::ostringstream out;
+ out << "Instance " << lod_model->mLabel << " LOD " << i << " Verts: " << cur_verts;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+
+ out.str("");
+ out << "Instance " << lod_model->mLabel << " LOD " << i << " Tris: " << cur_tris;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+
+ out.str("");
+ out << "Instance " << lod_model->mLabel << " LOD " << i << " Faces: " << cur_submeshes;
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+
+ out.str("");
+ LLModel::material_list::iterator mat_iter = lod_model->mMaterialList.begin();
+ while (mat_iter != lod_model->mMaterialList.end())
+ {
+ out << "Instance " << lod_model->mLabel << " LOD " << i << " Material " << *(mat_iter);
+ LL_INFOS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ out.str("");
+ mat_iter++;
+ }
+ }
+
+ //add this model to the lod total
+ total_tris[i] += cur_tris;
+ total_verts[i] += cur_verts;
+ total_submeshes[i] += cur_submeshes;
+
+ //store this model's counts to asset data
+ tris[i].push_back(cur_tris);
+ verts[i].push_back(cur_verts);
+ submeshes[i].push_back(cur_submeshes);
+ }
+ }
+ }
+
+ if (mMaxTriangleLimit == 0)
+ {
+ mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
+ }
+
+ mHasDegenerate = false;
+ {//check for degenerate triangles in physics mesh
+ U32 lod = LLModel::LOD_PHYSICS;
+ const LLVector4a scale(0.5f);
+ for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)
+ { //for each model in the lod
+ if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty())
+ { //no decomp exists
+ S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
+ for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
+ for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate;)
+ {
+ U16 index_a = face.mIndices[k + 0];
+ U16 index_b = face.mIndices[k + 1];
+ U16 index_c = face.mIndices[k + 2];
+
+ if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case
+ {
+ LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL;
+ }
+ else
+ {
+ LLVector4a v1; v1.setMul(face.mPositions[index_a], scale);
+ LLVector4a v2; v2.setMul(face.mPositions[index_b], scale);
+ LLVector4a v3; v3.setMul(face.mPositions[index_c], scale);
+ if (ll_is_degenerate(v1, v2, v3))
+ {
+ mHasDegenerate = true;
+ }
+ }
+ k += 3;
+ }
+ }
+ }
+ }
+ }
+
+ // flag degenerates here rather than deferring to a MAV error later
+ mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear
+ auto degenerateIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+ degenerateIcon->setVisible(mHasDegenerate);
+ if (mHasDegenerate)
+ {
+ has_physics_error |= PhysicsError::DEGENERATE;
+ mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles"));
+ LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error");
+ degenerateIcon->setImage(img);
+ }
+
+ mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
+
+ std::string mesh_status_na = mFMP->getString("mesh_status_na");
+
+ S32 upload_status[LLModel::LOD_HIGH + 1];
+
+ mModelNoErrors = true;
+
+ const U32 lod_high = LLModel::LOD_HIGH;
+ U32 high_submodel_count = mModel[lod_high].size() - countRootModels(mModel[lod_high]);
+
+ for (S32 lod = 0; lod <= lod_high; ++lod)
+ {
+ upload_status[lod] = 0;
+
+ std::string message = "mesh_status_good";
+
+ if (total_tris[lod] > 0)
+ {
+ mFMP->childSetValue(lod_triangles_name[lod], llformat("%d", total_tris[lod]));
+ mFMP->childSetValue(lod_vertices_name[lod], llformat("%d", total_verts[lod]));
+ }
+ else
+ {
+ if (lod == lod_high)
+ {
+ upload_status[lod] = 2;
+ message = "mesh_status_missing_lod";
+ }
+ else
+ {
+ for (S32 i = lod - 1; i >= 0; --i)
+ {
+ if (total_tris[i] > 0)
+ {
+ upload_status[lod] = 2;
+ message = "mesh_status_missing_lod";
+ }
+ }
+ }
+
+ mFMP->childSetValue(lod_triangles_name[lod], mesh_status_na);
+ mFMP->childSetValue(lod_vertices_name[lod], mesh_status_na);
+ }
+
+ if (lod != lod_high)
+ {
+ if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high])
+ { //number of submeshes is different
+ message = "mesh_status_submesh_mismatch";
+ upload_status[lod] = 2;
+ }
+ else if (mModel[lod].size() - countRootModels(mModel[lod]) != high_submodel_count)
+ {//number of submodels is different, not all faces are matched correctly.
+ message = "mesh_status_submesh_mismatch";
+ upload_status[lod] = 2;
+ // Note: Submodels in instance were loaded from higher LOD and as result face count
+ // returns same value and total_submeshes[lod] is identical to high_lod one.
+ }
+ else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size())
+ { //number of meshes is different
+ message = "mesh_status_mesh_mismatch";
+ upload_status[lod] = 2;
+ }
+ else if (!verts[lod].empty())
+ {
+ S32 sum_verts_higher_lod = 0;
+ S32 sum_verts_this_lod = 0;
+ for (U32 i = 0; i < verts[lod].size(); ++i)
+ {
+ sum_verts_higher_lod += ((i < verts[lod + 1].size()) ? verts[lod + 1][i] : 0);
+ sum_verts_this_lod += verts[lod][i];
+ }
+
+ if ((sum_verts_higher_lod > 0) &&
+ (sum_verts_this_lod > sum_verts_higher_lod))
+ {
+ //too many vertices in this lod
+ message = "mesh_status_too_many_vertices";
+ upload_status[lod] = 1;
+ }
+ }
+ }
+
+ LLIconCtrl* icon = mFMP->getChild<LLIconCtrl>(lod_icon_name[lod]);
+ LLUIImagePtr img = LLUI::getUIImage(lod_status_image[upload_status[lod]]);
+ icon->setVisible(true);
+ icon->setImage(img);
+
+ if (upload_status[lod] >= 2)
+ {
+ mModelNoErrors = false;
+ }
+
+ if (lod == mPreviewLOD)
+ {
+ mFMP->childSetValue("lod_status_message_text", mFMP->getString(message));
+ icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon");
+ icon->setImage(img);
+ }
+
+ updateLodControls(lod);
+ }
+
+
+ //warn if hulls have more than 256 points in them
+ BOOL physExceededVertexLimit = FALSE;
+ for (U32 i = 0; mModelNoErrors && i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
+ {
+ LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i];
+
+ if (mdl)
+ {
+ for (U32 j = 0; j < mdl->mPhysics.mHull.size(); ++j)
+ {
+ if (mdl->mPhysics.mHull[j].size() > 256)
+ {
+ physExceededVertexLimit = TRUE;
+ LL_INFOS() << "Physical model " << mdl->mLabel << " exceeds vertex per hull limitations." << LL_ENDL;
+ break;
+ }
+ }
+ }
+ }
+
+ if (physExceededVertexLimit)
+ {
+ has_physics_error |= PhysicsError::TOOMANYVERTSINHULL;
+ }
+
+ if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use.
+ mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit);
+ LLIconCtrl* physStatusIcon = mFMP->getChild<LLIconCtrl>("physics_status_message_icon");
+ physStatusIcon->setVisible(physExceededVertexLimit);
+ if (physExceededVertexLimit)
+ {
+ mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded"));
+ LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning");
+ physStatusIcon->setImage(img);
+ }
+ }
+
+ if (getLoadState() >= LLModelLoader::ERROR_PARSING)
+ {
+ mModelNoErrors = false;
+ LL_INFOS() << "Loader returned errors, model can't be uploaded" << LL_ENDL;
+ }
+
+ bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean();
+ bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean();
+
+ if (uploadingSkin)
+ {
+ if (uploadingJointPositions && !isRigValidForJointPositionUpload())
+ {
+ mModelNoErrors = false;
+ LL_INFOS() << "Invalid rig, there might be issues with uploading Joint positions" << LL_ENDL;
+ }
+ }
+
+ if (mModelNoErrors && mModelLoader)
+ {
+ if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
+ {
+ // Some textures are still loading, prevent upload until they are done
+ mModelNoErrors = false;
+ }
+ }
+
+ if (!mModelNoErrors || mHasDegenerate)
+ {
+ mFMP->childDisable("ok_btn");
+ mFMP->childDisable("calculate_btn");
+ }
+ else
+ {
+ mFMP->childEnable("ok_btn");
+ mFMP->childEnable("calculate_btn");
+ }
+
+ if (mModelNoErrors && mLodsWithParsingError.empty())
+ {
+ mFMP->childEnable("calculate_btn");
+ }
+ else
+ {
+ mFMP->childDisable("calculate_btn");
+ }
+
+ //add up physics triangles etc
+ S32 phys_tris = 0;
+ S32 phys_hulls = 0;
+ S32 phys_points = 0;
+
+ //get the triangle count for the whole scene
+ for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
+ {
+ LLModel* model = instance->mModel;
+ if (model)
+ {
+ S32 cur_submeshes = model->getNumVolumeFaces();
+
+ LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
+
+ if (!decomp.empty())
+ {
+ phys_hulls += decomp.size();
+ for (U32 i = 0; i < decomp.size(); ++i)
+ {
+ phys_points += decomp[i].size();
+ }
+ }
+ else
+ { //choose physics shape OR decomposition, can't use both
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = model->getVolumeFace(j);
+ phys_tris += face.mNumIndices / 3;
+ }
+ }
+ }
+ }
+ }
+
+ if (phys_tris > 0)
+ {
+ mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", llformat("%d", phys_tris));
+ }
+ else
+ {
+ mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", mesh_status_na);
+ }
+
+ if (phys_hulls > 0)
+ {
+ mFMP->childSetTextArg("physics_hulls", "[HULLS]", llformat("%d", phys_hulls));
+ mFMP->childSetTextArg("physics_points", "[POINTS]", llformat("%d", phys_points));
+ }
+ else
+ {
+ mFMP->childSetTextArg("physics_hulls", "[HULLS]", mesh_status_na);
+ mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na);
+ }
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp)
+ {
+ if (phys_tris > 0 || phys_hulls > 0)
+ {
+ if (!fmp->isViewOptionEnabled("show_physics"))
+ {
+ fmp->enableViewOption("show_physics");
+ mViewOption["show_physics"] = true;
+ fmp->childSetValue("show_physics", true);
+ }
+ }
+ else
+ {
+ fmp->disableViewOption("show_physics");
+ mViewOption["show_physics"] = false;
+ fmp->childSetValue("show_physics", false);
+
+ }
+
+ //bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean();
+
+ //fmp->childSetEnabled("physics_optimize", !use_hull);
+
+ bool enable = (phys_tris > 0 || phys_hulls > 0) && fmp->mCurRequest.empty();
+ //enable = enable && !use_hull && fmp->childGetValue("physics_optimize").asBoolean();
+
+ //enable/disable "analysis" UI
+ LLPanel* panel = fmp->getChild<LLPanel>("physics analysis");
+ LLView* child = panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(enable);
+ child = panel->findNextSibling(child);
+ }
+
+ enable = phys_hulls > 0 && fmp->mCurRequest.empty();
+ //enable/disable "simplification" UI
+ panel = fmp->getChild<LLPanel>("physics simplification");
+ child = panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(enable);
+ child = panel->findNextSibling(child);
+ }
+
+ if (fmp->mCurRequest.empty())
+ {
+ fmp->childSetVisible("Simplify", true);
+ fmp->childSetVisible("simplify_cancel", false);
+ fmp->childSetVisible("Decompose", true);
+ fmp->childSetVisible("decompose_cancel", false);
+
+ if (phys_hulls > 0)
+ {
+ fmp->childEnable("Simplify");
+ }
+
+ if (phys_tris || phys_hulls > 0)
+ {
+ fmp->childEnable("Decompose");
+ }
+ }
+ else
+ {
+ fmp->childEnable("simplify_cancel");
+ fmp->childEnable("decompose_cancel");
+ }
+ }
+
+
+ LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo");
+ S32 which_mode = 0;
+ S32 file_mode = 1;
+ if (iface)
+ {
+ which_mode = iface->getFirstSelectedIndex();
+ file_mode = iface->getItemCount() - 1;
+ }
+
+ if (which_mode == file_mode)
+ {
+ mFMP->childEnable("physics_file");
+ mFMP->childEnable("physics_browse");
+ }
+ else
+ {
+ mFMP->childDisable("physics_file");
+ mFMP->childDisable("physics_browse");
+ }
+
+ LLSpinCtrl* crease = mFMP->getChild<LLSpinCtrl>("crease_angle");
+
+ if (mRequestedCreaseAngle[mPreviewLOD] == -1.f)
+ {
+ mFMP->childSetColor("crease_label", LLColor4::grey);
+ crease->forceSetValue(75.f);
+ }
+ else
+ {
+ mFMP->childSetColor("crease_label", LLColor4::white);
+ crease->forceSetValue(mRequestedCreaseAngle[mPreviewLOD]);
+ }
+
+ mModelUpdatedSignal(true);
+
+}
+
+void LLModelPreview::updateLodControls(S32 lod)
+{
+ if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::LOD_HIGH)
+ {
+ std::ostringstream out;
+ out << "Invalid level of detail: " << lod;
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, false);
+ assert(lod >= LLModel::LOD_IMPOSTOR && lod <= LLModel::LOD_HIGH);
+ return;
+ }
+
+ const char* lod_controls[] =
+ {
+ "lod_mode_",
+ "lod_triangle_limit_",
+ "lod_error_threshold_"
+ };
+ const U32 num_lod_controls = sizeof(lod_controls) / sizeof(char*);
+
+ const char* file_controls[] =
+ {
+ "lod_browse_",
+ "lod_file_",
+ };
+ const U32 num_file_controls = sizeof(file_controls) / sizeof(char*);
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (!fmp) return;
+
+ LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[lod]);
+ if (!lod_combo) return;
+
+ S32 lod_mode = lod_combo->getCurrentIndex();
+ if (lod_mode == LOD_FROM_FILE) // LoD from file
+ {
+ fmp->mLODMode[lod] = 0;
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childSetVisible(file_controls[i] + lod_name[lod], true);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childSetVisible(lod_controls[i] + lod_name[lod], false);
+ }
+ }
+ else if (lod_mode == USE_LOD_ABOVE) // use LoD above
+ {
+ fmp->mLODMode[lod] = 2;
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->childSetVisible(file_controls[i] + lod_name[lod], false);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->childSetVisible(lod_controls[i] + lod_name[lod], false);
+ }
+
+ if (lod < LLModel::LOD_HIGH)
+ {
+ mModel[lod] = mModel[lod + 1];
+ mScene[lod] = mScene[lod + 1];
+ mVertexBuffer[lod].clear();
+
+ // Also update lower LoD
+ if (lod > LLModel::LOD_IMPOSTOR)
+ {
+ updateLodControls(lod - 1);
+ }
+ }
+ }
+ else // auto generate, the default case for all LoDs except High
+ {
+ fmp->mLODMode[lod] = 1;
+
+ //don't actually regenerate lod when refreshing UI
+ mLODFrozen = true;
+
+ for (U32 i = 0; i < num_file_controls; ++i)
+ {
+ mFMP->getChildView(file_controls[i] + lod_name[lod])->setVisible(false);
+ }
+
+ for (U32 i = 0; i < num_lod_controls; ++i)
+ {
+ mFMP->getChildView(lod_controls[i] + lod_name[lod])->setVisible(true);
+ }
+
+
+ LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold_" + lod_name[lod]);
+ LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit_" + lod_name[lod]);
+
+ limit->setMaxValue(mMaxTriangleLimit);
+ limit->forceSetValue(mRequestedTriangleCount[lod]);
+
+ threshold->forceSetValue(mRequestedErrorThreshold[lod]);
+
+ mFMP->getChild<LLComboBox>("lod_mode_" + lod_name[lod])->selectNthItem(mRequestedLoDMode[lod]);
+
+ if (mRequestedLoDMode[lod] == 0)
+ {
+ limit->setVisible(true);
+ threshold->setVisible(false);
+
+ limit->setMaxValue(mMaxTriangleLimit);
+ limit->setIncrement(mMaxTriangleLimit / 32);
+ }
+ else
+ {
+ limit->setVisible(false);
+ threshold->setVisible(true);
+ }
+
+ mLODFrozen = false;
+ }
+}
+
+void LLModelPreview::setPreviewTarget(F32 distance)
+{
+ mCameraDistance = distance;
+ mCameraZoom = 1.f;
+ mCameraPitch = 0.f;
+ mCameraYaw = 0.f;
+ mCameraOffset.clearVec();
+}
+
+void LLModelPreview::clearBuffers()
+{
+ for (U32 i = 0; i < 6; i++)
+ {
+ mVertexBuffer[i].clear();
+ }
+}
+
+void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
+{
+ U32 tri_count = 0;
+ U32 vertex_count = 0;
+ U32 mesh_count = 0;
+
+
+ LLModelLoader::model_list* model = NULL;
+
+ if (lod < 0 || lod > 4)
+ {
+ model = &mBaseModel;
+ lod = 5;
+ }
+ else
+ {
+ model = &(mModel[lod]);
+ }
+
+ if (!mVertexBuffer[lod].empty())
+ {
+ mVertexBuffer[lod].clear();
+ }
+
+ mVertexBuffer[lod].clear();
+
+ LLModelLoader::model_list::iterator base_iter = mBaseModel.begin();
+
+ for (LLModelLoader::model_list::iterator iter = model->begin(); iter != model->end(); ++iter)
+ {
+ LLModel* mdl = *iter;
+ if (!mdl)
+ {
+ continue;
+ }
+
+ LLModel* base_mdl = *base_iter;
+ base_iter++;
+
+ S32 num_faces = mdl->getNumVolumeFaces();
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ const LLVolumeFace &vf = mdl->getVolumeFace(i);
+ U32 num_vertices = vf.mNumVertices;
+ U32 num_indices = vf.mNumIndices;
+
+ if (!num_vertices || !num_indices)
+ {
+ continue;
+ }
+
+ LLVertexBuffer* vb = NULL;
+
+ bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
+
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+
+ if (skinned)
+ {
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ vb = new LLVertexBuffer(mask, 0);
+
+ if (!vb->allocateBuffer(num_vertices, num_indices, TRUE))
+ {
+ // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview
+ std::ostringstream out;
+ out << "Failed to allocate Vertex Buffer for model preview ";
+ out << num_vertices << " vertices and ";
+ out << num_indices << " indices";
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, true);
+ }
+
+ LLStrider<LLVector3> vertex_strider;
+ LLStrider<LLVector3> normal_strider;
+ LLStrider<LLVector2> tc_strider;
+ LLStrider<U16> index_strider;
+ LLStrider<LLVector4> weights_strider;
+
+ vb->getVertexStrider(vertex_strider);
+ vb->getIndexStrider(index_strider);
+
+ if (skinned)
+ {
+ vb->getWeight4Strider(weights_strider);
+ }
+
+ LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)vf.mPositions, num_vertices * 4 * sizeof(F32));
+
+ if (vf.mTexCoords)
+ {
+ vb->getTexCoord0Strider(tc_strider);
+ S32 tex_size = (num_vertices * 2 * sizeof(F32) + 0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)vf.mTexCoords, tex_size);
+ }
+
+ if (vf.mNormals)
+ {
+ vb->getNormalStrider(normal_strider);
+ LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32));
+ }
+
+ if (skinned)
+ {
+ for (U32 i = 0; i < num_vertices; i++)
+ {
+ //find closest weight to vf.mVertices[i].mPosition
+ LLVector3 pos(vf.mPositions[i].getF32ptr());
+
+ const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
+
+ LLVector4 w(0, 0, 0, 0);
+
+ for (U32 i = 0; i < weight_list.size(); ++i)
+ {
+ F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f);
+ F32 joint = (F32)weight_list[i].mJointIdx;
+ w.mV[i] = joint + wght;
+ llassert(w.mV[i] - (S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values
+ //should not cause floating point precision issues.
+ }
+
+ *(weights_strider++) = w;
+ }
+ }
+
+ // build indices
+ for (U32 i = 0; i < num_indices; i++)
+ {
+ *(index_strider++) = vf.mIndices[i];
+ }
+
+ mVertexBuffer[lod][mdl].push_back(vb);
+
+ vertex_count += num_vertices;
+ tri_count += num_indices / 3;
+ ++mesh_count;
+
+ }
+ }
+}
+
+void LLModelPreview::update()
+{
+ if (mGenLOD)
+ {
+ bool subscribe_for_generation = mLodsQuery.empty();
+ mGenLOD = false;
+ mDirty = true;
+ mLodsQuery.clear();
+
+ for (S32 lod = LLModel::LOD_HIGH; lod >= 0; --lod)
+ {
+ // adding all lods into query for generation
+ mLodsQuery.push_back(lod);
+ }
+
+ if (subscribe_for_generation)
+ {
+ doOnIdleRepeating(lodQueryCallback);
+ }
+ }
+
+ if (mDirty && mLodsQuery.empty())
+ {
+ mDirty = false;
+ mResourceCost = calcResourceCost();
+ refresh();
+ updateStatusMessages();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// createPreviewAvatar
+//-----------------------------------------------------------------------------
+void LLModelPreview::createPreviewAvatar(void)
+{
+ mPreviewAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
+ if (mPreviewAvatar)
+ {
+ mPreviewAvatar->createDrawable(&gPipeline);
+ mPreviewAvatar->mSpecialRenderMode = 1;
+ mPreviewAvatar->startMotion(ANIM_AGENT_STAND);
+ mPreviewAvatar->hideSkirt();
+ }
+ else
+ {
+ LL_INFOS() << "Failed to create preview avatar for upload model window" << LL_ENDL;
+ }
+}
+
+//static
+U32 LLModelPreview::countRootModels(LLModelLoader::model_list models)
+{
+ U32 root_models = 0;
+ model_list::iterator model_iter = models.begin();
+ while (model_iter != models.end())
+ {
+ LLModel* mdl = *model_iter;
+ if (mdl && mdl->mSubmodelID == 0)
+ {
+ root_models++;
+ }
+ model_iter++;
+ }
+ return root_models;
+}
+
+void LLModelPreview::loadedCallback(
+ LLModelLoader::scene& scene,
+ LLModelLoader::model_list& model_list,
+ S32 lod,
+ void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview && !LLModelPreview::sIgnoreLoadedCallback)
+ {
+ // Load loader's warnings into floater's log tab
+ const LLSD out = pPreview->mModelLoader->logOut();
+ LLSD::array_const_iterator iter_out = out.beginArray();
+ LLSD::array_const_iterator end_out = out.endArray();
+ for (; iter_out != end_out; ++iter_out)
+ {
+ if (iter_out->has("Message"))
+ {
+ LLFloaterModelPreview::addStringToLog(iter_out->get("Message"), *iter_out, true, pPreview->mModelLoader->mLod);
+ }
+ }
+ pPreview->mModelLoader->clearLog();
+ pPreview->loadModelCallback(lod); // removes mModelLoader in some cases
+ if (pPreview->mLookUpLodFiles && (lod != LLModel::LOD_HIGH))
+ {
+ pPreview->lookupLODModelFiles(lod);
+ }
+ }
+
+}
+
+void LLModelPreview::lookupLODModelFiles(S32 lod)
+{
+ if (lod == LLModel::LOD_PHYSICS)
+ {
+ mLookUpLodFiles = false;
+ return;
+ }
+ S32 next_lod = (lod - 1 >= LLModel::LOD_IMPOSTOR) ? lod - 1 : LLModel::LOD_PHYSICS;
+
+ std::string lod_filename = mLODFile[LLModel::LOD_HIGH];
+ std::string ext = ".dae";
+ std::string::size_type i = lod_filename.rfind(ext);
+ if (i != std::string::npos)
+ {
+ lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext);
+ }
+ if (gDirUtilp->fileExists(lod_filename))
+ {
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp)
+ {
+ fmp->setCtrlLoadFromFile(next_lod);
+ }
+ loadModel(lod_filename, next_lod);
+ }
+ else
+ {
+ lookupLODModelFiles(next_lod);
+ }
+}
+
+void LLModelPreview::stateChangedCallback(U32 state, void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview)
+ {
+ pPreview->setLoadState(state);
+ }
+}
+
+LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque)
+{
+ LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
+ if (pPreview)
+ {
+ return pPreview->getPreviewAvatar()->getJoint(str);
+ }
+ return NULL;
+}
+
+U32 LLModelPreview::loadTextures(LLImportMaterial& material, void* opaque)
+{
+ (void)opaque;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ material.mOpaqueData = new LLPointer< LLViewerFetchedTexture >;
+ LLPointer< LLViewerFetchedTexture >& tex = (*reinterpret_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData));
+
+ tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(material.mDiffuseMapFilename), FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
+ tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, opaque, NULL, FALSE);
+ tex->forceToSaveRawImage(0, F32_MAX);
+ material.setDiffuseMap(tex->getID()); // record tex ID
+ return 1;
+ }
+
+ material.mOpaqueData = NULL;
+ return 0;
+}
+
+void LLModelPreview::addEmptyFace(LLModel* pTarget)
+{
+ U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
+
+ buff->allocateBuffer(1, 3, true);
+ memset((U8*)buff->getMappedData(), 0, buff->getSize());
+ memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize());
+
+ buff->validateRange(0, buff->getNumVerts() - 1, buff->getNumIndices(), 0);
+
+ LLStrider<LLVector3> pos;
+ LLStrider<LLVector3> norm;
+ LLStrider<LLVector2> tc;
+ LLStrider<U16> index;
+
+ buff->getVertexStrider(pos);
+
+ if (type_mask & LLVertexBuffer::MAP_NORMAL)
+ {
+ buff->getNormalStrider(norm);
+ }
+ if (type_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ buff->getTexCoord0Strider(tc);
+ }
+
+ buff->getIndexStrider(index);
+
+ //resize face array
+ int faceCnt = pTarget->getNumVolumeFaces();
+ pTarget->setNumVolumeFaces(faceCnt + 1);
+ pTarget->setVolumeFaceData(faceCnt + 1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices());
+
+}
+
+//-----------------------------------------------------------------------------
+// render()
+//-----------------------------------------------------------------------------
+// Todo: we shouldn't be setting all those UI elements on render.
+// Note: Render happens each frame with skinned avatars
+BOOL LLModelPreview::render()
+{
+ assert_main_thread();
+
+ LLMutexLock lock(this);
+ mNeedsUpdate = FALSE;
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ bool edges = mViewOption["show_edges"];
+ bool joint_overrides = mViewOption["show_joint_overrides"];
+ bool joint_positions = mViewOption["show_joint_positions"];
+ bool skin_weight = mViewOption["show_skin_weight"];
+ bool textures = mViewOption["show_textures"];
+ bool physics = mViewOption["show_physics"];
+
+ S32 width = getWidth();
+ S32 height = getHeight();
+
+ LLGLSUIDefault def; // GL_BLEND, GL_ALPHA_TEST, GL_CULL_FACE, depth test
+ LLGLDisable no_blend(GL_BLEND);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLDepthTest depth(GL_FALSE); // SL-12781 disable z-buffer to render background color
+ LLGLDisable fog(GL_FOG);
+
+ {
+ if (use_shaders)
+ {
+ gUIProgram.bind();
+ }
+ //clear background to grey
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, width, 0.0f, height, -1.0f, 1.0f);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.color4fv(PREVIEW_CANVAS_COL.mV);
+ gl_rect_2d_simple(width, height);
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ if (use_shaders)
+ {
+ gUIProgram.unbind();
+ }
+ }
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+
+ bool has_skin_weights = false;
+ bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
+ bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
+
+ if (upload_joints != mLastJointUpdate)
+ {
+ mLastJointUpdate = upload_joints;
+ if (fmp)
+ {
+ fmp->clearAvatarTab();
+ }
+ }
+
+ for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
+ {
+ LLModelInstance& instance = *model_iter;
+ LLModel* model = instance.mModel;
+ model->mPelvisOffset = mPelvisZOffset;
+ if (!model->mSkinWeights.empty())
+ {
+ has_skin_weights = true;
+ }
+ }
+ }
+
+ if (has_skin_weights && lodsReady())
+ { //model has skin weights, enable view options for skin weights and joint positions
+ U32 flags = getLegacyRigFlags();
+ if (fmp)
+ {
+ if (flags == LEGACY_RIG_OK)
+ {
+ if (mFirstSkinUpdate)
+ {
+ // auto enable weight upload if weights are present
+ // (note: all these UI updates need to be somewhere that is not render)
+ mViewOption["show_skin_weight"] = true;
+ skin_weight = true;
+ fmp->childSetValue("upload_skin", true);
+ mFirstSkinUpdate = false;
+ }
+
+ fmp->enableViewOption("show_skin_weight");
+ fmp->setViewOptionEnabled("show_joint_overrides", skin_weight);
+ fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
+ mFMP->childEnable("upload_skin");
+ mFMP->childSetValue("show_skin_weight", skin_weight);
+
+ }
+ else if ((flags & LEGACY_RIG_FLAG_TOO_MANY_JOINTS) > 0)
+ {
+ mFMP->childSetVisible("skin_too_many_joints", true);
+ }
+ else if ((flags & LEGACY_RIG_FLAG_UNKNOWN_JOINT) > 0)
+ {
+ mFMP->childSetVisible("skin_unknown_joint", true);
+ }
+ }
+ }
+ else
+ {
+ mFMP->childDisable("upload_skin");
+ if (fmp)
+ {
+ mViewOption["show_skin_weight"] = false;
+ fmp->disableViewOption("show_skin_weight");
+ fmp->disableViewOption("show_joint_overrides");
+ fmp->disableViewOption("show_joint_positions");
+
+ skin_weight = false;
+ mFMP->childSetValue("show_skin_weight", false);
+ fmp->setViewOptionEnabled("show_skin_weight", skin_weight);
+ }
+ }
+
+ if (upload_skin && !has_skin_weights)
+ { //can't upload skin weights if model has no skin weights
+ mFMP->childSetValue("upload_skin", false);
+ upload_skin = false;
+ }
+
+ if (!upload_skin && upload_joints)
+ { //can't upload joints if not uploading skin weights
+ mFMP->childSetValue("upload_joints", false);
+ upload_joints = false;
+ }
+
+ if (fmp)
+ {
+ if (upload_skin)
+ {
+ // will populate list of joints
+ fmp->updateAvatarTab(upload_joints);
+ }
+ else
+ {
+ fmp->clearAvatarTab();
+ }
+ }
+
+ if (upload_skin && upload_joints)
+ {
+ mFMP->childEnable("lock_scale_if_joint_position");
+ }
+ else
+ {
+ mFMP->childDisable("lock_scale_if_joint_position");
+ mFMP->childSetValue("lock_scale_if_joint_position", false);
+ }
+
+ //Only enable joint offsets if it passed the earlier critiquing
+ if (isRigValidForJointPositionUpload())
+ {
+ mFMP->childSetEnabled("upload_joints", upload_skin);
+ }
+
+ F32 explode = mFMP->childGetValue("physics_explode").asReal();
+
+ LLGLDepthTest gls_depth(GL_TRUE); // SL-12781 re-enable z-buffer for 3D model preview
+
+ LLRect preview_rect;
+
+ preview_rect = mFMP->getChildView("preview_panel")->getRect();
+
+ F32 aspect = (F32)preview_rect.getWidth() / preview_rect.getHeight();
+
+ LLViewerCamera::getInstance()->setAspect(aspect);
+
+ LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+
+ LLVector3 offset = mCameraOffset;
+ LLVector3 target_pos = mPreviewTarget + offset;
+
+ F32 z_near = 0.001f;
+ F32 z_far = mCameraDistance*10.0f + mPreviewScale.magVec() + mCameraOffset.magVec();
+
+ if (skin_weight)
+ {
+ target_pos = getPreviewAvatar()->getPositionAgent() + offset;
+ z_near = 0.01f;
+ z_far = 1024.f;
+
+ //render avatar previews every frame
+ refresh();
+ }
+
+ if (use_shaders)
+ {
+ gObjectPreviewProgram.bind();
+ }
+
+ gGL.loadIdentity();
+ gPipeline.enableLightsPreview();
+
+ LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
+ LLQuaternion(mCameraYaw, LLVector3::z_axis);
+
+ LLQuaternion av_rot = camera_rot;
+ F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
+ LLViewerCamera::getInstance()->setOriginAndLookAt(
+ target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos); // point of interest
+
+
+ z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
+
+ LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far);
+
+ stop_glerror();
+
+ gGL.pushMatrix();
+ gGL.color4fv(PREVIEW_EDGE_COL.mV);
+
+ const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
+
+ LLGLEnable normalize(GL_NORMALIZE);
+
+ if (!mBaseModel.empty() && mVertexBuffer[5].empty())
+ {
+ genBuffers(-1, skin_weight);
+ //genBuffers(3);
+ //genLODs();
+ }
+
+ if (!mModel[mPreviewLOD].empty())
+ {
+ mFMP->childEnable("reset_btn");
+
+ bool regen = mVertexBuffer[mPreviewLOD].empty();
+ if (!regen)
+ {
+ const std::vector<LLPointer<LLVertexBuffer> >& vb_vec = mVertexBuffer[mPreviewLOD].begin()->second;
+ if (!vb_vec.empty())
+ {
+ const LLVertexBuffer* buff = vb_vec[0];
+ regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight;
+ }
+ else
+ {
+ LL_INFOS() << "Vertex Buffer[" << mPreviewLOD << "]" << " is EMPTY!!!" << LL_ENDL;
+ regen = TRUE;
+ }
+ }
+
+ if (regen)
+ {
+ genBuffers(mPreviewLOD, skin_weight);
+ }
+
+ if (!skin_weight)
+ {
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model = instance.mLOD[mPreviewLOD];
+
+ if (!model)
+ {
+ continue;
+ }
+
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
+
+ gGL.multMatrix((GLfloat*)mat.mMatrix);
+
+
+ U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
+ for (U32 i = 0; i < num_models; ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+
+ if (textures)
+ {
+ int materialCnt = instance.mModel->mMaterialList.size();
+ if (i < materialCnt)
+ {
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
+
+ gGL.diffuseColor4fv(material.mDiffuseColor.mV);
+
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
+ {
+ mTextureSet.insert(tex);
+ }
+ }
+ }
+ else
+ {
+ gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);
+ }
+
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
+ if (edges)
+ {
+ glLineWidth(PREVIEW_EDGE_WIDTH);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
+ }
+ gGL.popMatrix();
+ }
+
+ if (physics)
+ {
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ for (U32 pass = 0; pass < 2; pass++)
+ {
+ if (pass == 0)
+ { //depth only pass
+ gGL.setColorMask(false, false);
+ }
+ else
+ {
+ gGL.setColorMask(true, true);
+ }
+
+ //enable alpha blending on second pass but not first pass
+ LLGLState blend(GL_BLEND, pass);
+
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+
+ if (!model)
+ {
+ continue;
+ }
+
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
+
+ gGL.multMatrix((GLfloat*)mat.mMatrix);
+
+
+ bool render_mesh = true;
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
+ {
+ LLMutexLock(decomp->mMutex);
+
+ LLModel::Decomposition& physics = model->mPhysics;
+
+ if (!physics.mHull.empty())
+ {
+ render_mesh = false;
+
+ if (physics.mMesh.empty())
+ { //build vertex buffer for physics mesh
+ gMeshRepo.buildPhysicsMesh(physics);
+ }
+
+ if (!physics.mMesh.empty())
+ { //render hull instead of mesh
+ for (U32 i = 0; i < physics.mMesh.size(); ++i)
+ {
+ if (explode > 0.f)
+ {
+ gGL.pushMatrix();
+
+ LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters;
+ offset *= explode;
+
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+ }
+
+ static std::vector<LLColor4U> hull_colors;
+
+ if (i + 1 >= hull_colors.size())
+ {
+ hull_colors.push_back(LLColor4U(rand() % 128 + 127, rand() % 128 + 127, rand() % 128 + 127, 128));
+ }
+
+ gGL.diffuseColor4ubv(hull_colors[i].mV);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
+ }
+ }
+ }
+ }
+ }
+
+ if (render_mesh)
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+
+ U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ if (pass > 0){
+ for (U32 i = 0; i < num_models; ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.diffuseColor4fv(PREVIEW_PSYH_FILL_COL.mV);
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+
+ gGL.diffuseColor4fv(PREVIEW_PSYH_EDGE_COL.mV);
+ glLineWidth(PREVIEW_PSYH_EDGE_WIDTH);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
+ }
+ }
+ gGL.popMatrix();
+ }
+
+ // only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks]
+ if (mHasDegenerate)
+ {
+ glLineWidth(PREVIEW_DEG_EDGE_WIDTH);
+ glPointSize(PREVIEW_DEG_POINT_SIZE);
+ gPipeline.enableLightsFullbright();
+ //show degenerate triangles
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ LLGLDisable cull(GL_CULL_FACE);
+ gGL.diffuseColor4f(1.f, 0.f, 0.f, 1.f);
+ const LLVector4a scale(0.5f);
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+
+ if (!model)
+ {
+ continue;
+ }
+
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
+
+ gGL.multMatrix((GLfloat*)mat.mMatrix);
+
+
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
+ {
+ LLMutexLock(decomp->mMutex);
+
+ LLModel::Decomposition& physics = model->mPhysics;
+
+ if (physics.mHull.empty())
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+
+ U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
+ for (U32 v = 0; v < num_models; ++v)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+
+ LLStrider<LLVector3> pos_strider;
+ buffer->getVertexStrider(pos_strider, 0);
+ LLVector4a* pos = (LLVector4a*)pos_strider.get();
+
+ LLStrider<U16> idx;
+ buffer->getIndexStrider(idx, 0);
+
+ for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
+ {
+ LLVector4a v1; v1.setMul(pos[*idx++], scale);
+ LLVector4a v2; v2.setMul(pos[*idx++], scale);
+ LLVector4a v3; v3.setMul(pos[*idx++], scale);
+
+ if (ll_is_degenerate(v1, v2, v3))
+ {
+ buffer->draw(LLRender::LINE_LOOP, 3, i);
+ buffer->draw(LLRender::POINTS, 3, i);
+ }
+ }
+ }
+ }
+ }
+
+ gGL.popMatrix();
+ }
+ glLineWidth(1.f);
+ glPointSize(1.f);
+ gPipeline.enableLightsPreview();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
+ }
+ }
+ }
+ else
+ {
+ target_pos = getPreviewAvatar()->getPositionAgent();
+ getPreviewAvatar()->clearAttachmentOverrides(); // removes pelvis fixup
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ getPreviewAvatar()->addPelvisFixup(mPelvisZOffset, fake_mesh_id);
+ bool pelvis_recalc = false;
+
+ LLViewerCamera::getInstance()->setOriginAndLookAt(
+ target_pos + ((LLVector3(camera_distance, 0.f, 0.f) + offset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos); // point of interest
+
+ for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
+ {
+ LLModelInstance& instance = *model_iter;
+ LLModel* model = instance.mModel;
+
+ if (!model->mSkinWeights.empty())
+ {
+ const LLMeshSkinInfo *skin = &model->mSkinInfo;
+ LLSkinningUtil::initJointNums(&model->mSkinInfo, getPreviewAvatar());// inits skin->mJointNums if nessesary
+ U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);
+ U32 bind_count = skin->mAlternateBindMatrix.size();
+
+ if (joint_overrides
+ && bind_count > 0
+ && joint_count == bind_count)
+ {
+ // mesh_id is used to determine which mesh gets to
+ // set the joint offset, in the event of a conflict. Since
+ // we don't know the mesh id yet, we can't guarantee that
+ // joint offsets will be applied with the same priority as
+ // in the uploaded model. If the file contains multiple
+ // meshes with conflicting joint offsets, preview may be
+ // incorrect.
+ LLUUID fake_mesh_id;
+ fake_mesh_id.generate();
+ for (U32 j = 0; j < joint_count; ++j)
+ {
+ LLJoint *joint = getPreviewAvatar()->getJoint(skin->mJointNums[j]);
+ if (joint)
+ {
+ const LLVector3& jointPos = skin->mAlternateBindMatrix[j].getTranslation();
+ if (joint->aboveJointPosThreshold(jointPos))
+ {
+ bool override_changed;
+ joint->addAttachmentPosOverride(jointPos, fake_mesh_id, "model", override_changed);
+
+ if (override_changed)
+ {
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if (joint->getName() == "mPelvis")// or skin->mJointNames[j]
+ {
+ pelvis_recalc = true;
+ }
+ }
+ if (skin->mLockScaleIfJointPosition)
+ {
+ // Note that unlike positions, there's no threshold check here,
+ // just a lock at the default value.
+ joint->addAttachmentScaleOverride(joint->getDefaultScale(), fake_mesh_id, "model");
+ }
+ }
+ }
+ }
+ }
+
+ for (U32 i = 0, e = mVertexBuffer[mPreviewLOD][model].size(); i < e; ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
+
+ const LLVolumeFace& face = model->getVolumeFace(i);
+
+ LLStrider<LLVector3> position;
+ buffer->getVertexStrider(position);
+
+ LLStrider<LLVector4> weight;
+ buffer->getWeight4Strider(weight);
+
+ //quick 'n dirty software vertex skinning
+
+ //build matrix palette
+
+ LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
+ LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, joint_count,
+ skin, getPreviewAvatar());
+
+ LLMatrix4a bind_shape_matrix;
+ bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ U32 max_joints = LLSkinningUtil::getMaxJointCount();
+ for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ {
+ LLMatrix4a final_mat;
+ F32 *wptr = weight[j].mV;
+ LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
+
+ //VECTORIZE THIS
+ LLVector4a& v = face.mPositions[j];
+
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+
+ position[j][0] = dst[0];
+ position[j][1] = dst[1];
+ position[j][2] = dst[2];
+ }
+
+ llassert(model->mMaterialList.size() > i);
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
+
+ buffer->setBuffer(type_mask & buffer->getTypeMask());
+ gGL.diffuseColor4fv(material.mDiffuseColor.mV);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
+ {
+ mTextureSet.insert(tex);
+ }
+
+ buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
+
+ if (edges)
+ {
+ gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
+ glLineWidth(PREVIEW_EDGE_WIDTH);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glLineWidth(1.f);
+ }
+ }
+ }
+ }
+ }
+
+ if (joint_positions)
+ {
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ if (shader)
+ {
+ gDebugProgram.bind();
+ }
+ getPreviewAvatar()->renderCollisionVolumes();
+ if (fmp->mTabContainer->getCurrentPanelIndex() == fmp->mAvatarTabIndex)
+ {
+ getPreviewAvatar()->renderBones(fmp->mSelectedJointName);
+ }
+ else
+ {
+ getPreviewAvatar()->renderBones();
+ }
+ if (shader)
+ {
+ shader->bind();
+ }
+ }
+
+ if (pelvis_recalc)
+ {
+ // size/scale recalculation
+ getPreviewAvatar()->postPelvisSetRecalc();
+ }
+ }
+ }
+
+ if (use_shaders)
+ {
+ gObjectPreviewProgram.unbind();
+ }
+
+ gGL.popMatrix();
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// refresh()
+//-----------------------------------------------------------------------------
+void LLModelPreview::refresh()
+{
+ mNeedsUpdate = TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// rotate()
+//-----------------------------------------------------------------------------
+void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians)
+{
+ mCameraYaw = mCameraYaw + yaw_radians;
+
+ mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
+}
+
+//-----------------------------------------------------------------------------
+// zoom()
+//-----------------------------------------------------------------------------
+void LLModelPreview::zoom(F32 zoom_amt)
+{
+ F32 new_zoom = mCameraZoom + zoom_amt;
+ // TODO: stop clamping in render
+ mCameraZoom = llclamp(new_zoom, 1.f, PREVIEW_ZOOM_LIMIT);
+}
+
+void LLModelPreview::pan(F32 right, F32 up)
+{
+ bool skin_weight = mViewOption["show_skin_weight"];
+ F32 camera_distance = skin_weight ? SKIN_WEIGHT_CAMERA_DISTANCE : mCameraDistance;
+ mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * camera_distance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * camera_distance / mCameraZoom, -1.f, 1.f);
+}
+
+void LLModelPreview::setPreviewLOD(S32 lod)
+{
+ lod = llclamp(lod, 0, (S32)LLModel::LOD_HIGH);
+
+ if (lod != mPreviewLOD)
+ {
+ mPreviewLOD = lod;
+
+ LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo");
+ combo_box->setCurrentByIndex((NUM_LOD - 1) - mPreviewLOD); // combo box list of lods is in reverse order
+ mFMP->childSetValue("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
+
+ LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor");
+ LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor");
+
+ for (S32 i = 0; i <= LLModel::LOD_HIGH; ++i)
+ {
+ const LLColor4& color = (i == lod) ? highlight_color : normal_color;
+
+ mFMP->childSetColor(lod_status_name[i], color);
+ mFMP->childSetColor(lod_label_name[i], color);
+ mFMP->childSetColor(lod_triangles_name[i], color);
+ mFMP->childSetColor(lod_vertices_name[i], color);
+ }
+
+ LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)mFMP;
+ if (fmp)
+ {
+ // make preview repopulate tab
+ fmp->clearAvatarTab();
+ }
+ }
+ refresh();
+ updateStatusMessages();
+}
+
+//static
+void LLModelPreview::textureLoadedCallback(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* src_aux,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLModelPreview* preview = (LLModelPreview*)userdata;
+ preview->refresh();
+
+ if (final && preview->mModelLoader)
+ {
+ if (preview->mModelLoader->mNumOfFetchingTextures > 0)
+ {
+ preview->mModelLoader->mNumOfFetchingTextures--;
+ }
+ }
+}
+
+// static
+bool LLModelPreview::lodQueryCallback()
+{
+ // not the best solution, but model preview belongs to floater
+ // so it is an easy way to check that preview still exists.
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp && fmp->mModelPreview)
+ {
+ LLModelPreview* preview = fmp->mModelPreview;
+ if (preview->mLodsQuery.size() > 0)
+ {
+ S32 lod = preview->mLodsQuery.back();
+ preview->mLodsQuery.pop_back();
+ preview->genLODs(lod);
+
+ if (preview->mLookUpLodFiles && (lod == LLModel::LOD_HIGH))
+ {
+ preview->lookupLODModelFiles(LLModel::LOD_HIGH);
+ }
+
+ // return false to continue cycle
+ return false;
+ }
+ }
+ // nothing to process
+ return true;
+}
+
+void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
+{
+ if (!mLODFrozen)
+ {
+ genLODs(lod, 3, enforce_tri_limit);
+ refresh();
+ }
+}
+
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
new file mode 100644
index 0000000000..3664a27a72
--- /dev/null
+++ b/indra/newview/llmodelpreview.h
@@ -0,0 +1,313 @@
+/**
+ * @file llmodelpreview.h
+ * @brief LLModelPreview class definition, class
+ * responsible for model preview inside LLFloaterModelPreview
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMODELPREVIEW_H
+#define LL_LLMODELPREVIEW_H
+
+#include "lldynamictexture.h"
+#include "llfloatermodelpreview.h"
+#include "llmeshrepository.h"
+#include "llmodelloader.h" //NUM_LOD
+#include "llmodel.h"
+
+class LLJoint;
+class LLVOAvatar;
+class LLTextBox;
+class LLVertexBuffer;
+class DAE;
+class daeElement;
+class domProfile_COMMON;
+class domInstance_geometry;
+class domNode;
+class domTranslate;
+class domController;
+class domSkin;
+class domMesh;
+
+// const strings needed by classes that use model preivew
+static const std::string lod_name[NUM_LOD + 1] =
+{
+ "lowest",
+ "low",
+ "medium",
+ "high",
+ "I went off the end of the lod_name array. Me so smart."
+};
+
+static const std::string lod_triangles_name[NUM_LOD + 1] =
+{
+ "lowest_triangles",
+ "low_triangles",
+ "medium_triangles",
+ "high_triangles",
+ "I went off the end of the lod_triangles_name array. Me so smart."
+};
+
+static const std::string lod_vertices_name[NUM_LOD + 1] =
+{
+ "lowest_vertices",
+ "low_vertices",
+ "medium_vertices",
+ "high_vertices",
+ "I went off the end of the lod_vertices_name array. Me so smart."
+};
+
+static const std::string lod_status_name[NUM_LOD + 1] =
+{
+ "lowest_status",
+ "low_status",
+ "medium_status",
+ "high_status",
+ "I went off the end of the lod_status_name array. Me so smart."
+};
+
+static const std::string lod_icon_name[NUM_LOD + 1] =
+{
+ "status_icon_lowest",
+ "status_icon_low",
+ "status_icon_medium",
+ "status_icon_high",
+ "I went off the end of the lod_status_name array. Me so smart."
+};
+
+static const std::string lod_status_image[NUM_LOD + 1] =
+{
+ "ModelImport_Status_Good",
+ "ModelImport_Status_Warning",
+ "ModelImport_Status_Error",
+ "I went off the end of the lod_status_image array. Me so smart."
+};
+
+static const std::string lod_label_name[NUM_LOD + 1] =
+{
+ "lowest_label",
+ "low_label",
+ "medium_label",
+ "high_label",
+ "I went off the end of the lod_label_name array. Me so smart."
+};
+
+class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
+{
+ LOG_CLASS(LLModelPreview);
+
+ typedef boost::signals2::signal<void(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
+ typedef boost::signals2::signal<void(void)> model_loaded_signal_t;
+ typedef boost::signals2::signal<void(bool)> model_updated_signal_t;
+
+public:
+
+ typedef enum
+ {
+ LOD_FROM_FILE = 0,
+ GENERATE,
+ USE_LOD_ABOVE,
+ } eLoDMode;
+
+public:
+ // Todo: model preview shouldn't need floater dependency, it
+ // should just expose data to floater, not control flaoter like it does
+ LLModelPreview(S32 width, S32 height, LLFloater* fmp);
+ virtual ~LLModelPreview();
+
+ void resetPreviewTarget();
+ void setPreviewTarget(F32 distance);
+ void setTexture(U32 name) { mTextureName = name; }
+
+ void setPhysicsFromLOD(S32 lod);
+ BOOL render();
+ void update();
+ void genBuffers(S32 lod, bool skinned);
+ void clearBuffers();
+ void refresh();
+ void rotate(F32 yaw_radians, F32 pitch_radians);
+ void zoom(F32 zoom_amt);
+ void pan(F32 right, F32 up);
+ virtual BOOL needsRender() { return mNeedsUpdate; }
+ void setPreviewLOD(S32 lod);
+ void clearModel(S32 lod);
+ void getJointAliases(JointMap& joint_map);
+ void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
+ void loadModelCallback(S32 lod);
+ bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); }
+ void queryLODs() { mGenLOD = true; };
+ void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
+ void generateNormals();
+ void restoreNormals();
+ U32 calcResourceCost();
+ void rebuildUploadData();
+ void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position);
+ void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position);
+ void clearIncompatible(S32 lod);
+ void updateStatusMessages();
+ void updateLodControls(S32 lod);
+ void clearGLODGroup();
+ void onLODParamCommit(S32 lod, bool enforce_tri_limit);
+ void addEmptyFace(LLModel* pTarget);
+
+ const bool getModelPivot(void) const { return mHasPivot; }
+ void setHasPivot(bool val) { mHasPivot = val; }
+ void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; }
+
+ //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
+ //Accessors for joint position upload friendly rigs
+ const bool isRigValidForJointPositionUpload(void) const { return mRigValidJointUpload; }
+ void setRigValidForJointPositionUpload(bool rigValid) { mRigValidJointUpload = rigValid; }
+
+ //Accessors for the legacy rigs
+ const bool isLegacyRigValid(void) const { return mLegacyRigFlags == 0; }
+ U32 getLegacyRigFlags() const { return mLegacyRigFlags; }
+ void setLegacyRigFlags(U32 rigFlags) { mLegacyRigFlags = rigFlags; }
+
+ static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata);
+ static bool lodQueryCallback();
+
+ boost::signals2::connection setDetailsCallback(const details_signal_t::slot_type& cb){ return mDetailsSignal.connect(cb); }
+ boost::signals2::connection setModelLoadedCallback(const model_loaded_signal_t::slot_type& cb){ return mModelLoadedSignal.connect(cb); }
+ boost::signals2::connection setModelUpdatedCallback(const model_updated_signal_t::slot_type& cb){ return mModelUpdatedSignal.connect(cb); }
+
+ void setLoadState(U32 state) { mLoadState = state; }
+ U32 getLoadState() { return mLoadState; }
+
+ static bool sIgnoreLoadedCallback;
+ std::vector<S32> mLodsQuery;
+ std::vector<S32> mLodsWithParsingError;
+ bool mHasDegenerate;
+
+protected:
+
+ static void loadedCallback(LLModelLoader::scene& scene, LLModelLoader::model_list& model_list, S32 lod, void* opaque);
+ static void stateChangedCallback(U32 state, void* opaque);
+
+ static LLJoint* lookupJointByName(const std::string&, void* opaque);
+ static U32 loadTextures(LLImportMaterial& material, void* opaque);
+
+ void lookupLODModelFiles(S32 lod);
+
+private:
+ //Utility function for controller vertex compare
+ bool verifyCount(int expected, int result);
+ //Creates the dummy avatar for the preview window
+ void createPreviewAvatar(void);
+ //Accessor for the dummy avatar
+ LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
+ // Count amount of original models, excluding sub-models
+ static U32 countRootModels(LLModelLoader::model_list models);
+
+protected:
+ friend class LLModelLoader;
+ friend class LLFloaterModelPreview;
+ friend class LLFloaterModelPreview::DecompRequest;
+ friend class LLPhysicsDecomp;
+
+ LLFloater* mFMP;
+
+ BOOL mNeedsUpdate;
+ bool mDirty;
+ bool mGenLOD;
+ U32 mTextureName;
+ F32 mCameraDistance;
+ F32 mCameraYaw;
+ F32 mCameraPitch;
+ F32 mCameraZoom;
+ LLVector3 mCameraOffset;
+ LLVector3 mPreviewTarget;
+ LLVector3 mPreviewScale;
+ S32 mPreviewLOD;
+ S32 mPhysicsSearchLOD;
+ U32 mResourceCost;
+ std::string mLODFile[LLModel::NUM_LODS];
+ bool mLoading;
+ U32 mLoadState;
+ bool mResetJoints;
+ bool mModelNoErrors;
+ bool mLookUpLodFiles;
+
+ std::map<std::string, bool> mViewOption;
+
+ //GLOD object parameters (must rebuild object if these change)
+ bool mLODFrozen;
+ F32 mBuildShareTolerance;
+ U32 mBuildQueueMode;
+ U32 mBuildOperator;
+ U32 mBuildBorderMode;
+ U32 mRequestedLoDMode[LLModel::NUM_LODS];
+ S32 mRequestedTriangleCount[LLModel::NUM_LODS];
+ F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
+ U32 mRequestedBuildOperator[LLModel::NUM_LODS];
+ U32 mRequestedQueueMode[LLModel::NUM_LODS];
+ U32 mRequestedBorderMode[LLModel::NUM_LODS];
+ F32 mRequestedShareTolerance[LLModel::NUM_LODS];
+ F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
+
+ LLModelLoader* mModelLoader;
+
+ LLModelLoader::scene mScene[LLModel::NUM_LODS];
+ LLModelLoader::scene mBaseScene;
+
+ LLModelLoader::model_list mModel[LLModel::NUM_LODS];
+ LLModelLoader::model_list mBaseModel;
+
+ typedef std::vector<LLVolumeFace> v_LLVolumeFace_t;
+ typedef std::vector<v_LLVolumeFace_t> vv_LLVolumeFace_t;
+
+ vv_LLVolumeFace_t mModelFacesCopy[LLModel::NUM_LODS];
+ vv_LLVolumeFace_t mBaseModelFacesCopy;
+
+ U32 mGroup;
+ std::map<LLPointer<LLModel>, U32> mObject;
+ U32 mMaxTriangleLimit;
+
+ LLMeshUploadThread::instance_list mUploadData;
+ std::set<LLViewerFetchedTexture * > mTextureSet;
+
+ //map of vertex buffers to models (one vertex buffer in vector per face in model
+ std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS + 1];
+
+ details_signal_t mDetailsSignal;
+ model_loaded_signal_t mModelLoadedSignal;
+ model_updated_signal_t mModelUpdatedSignal;
+
+ LLVector3 mModelPivot;
+ bool mHasPivot;
+
+ float mPelvisZOffset;
+
+ bool mRigValidJointUpload;
+ U32 mLegacyRigFlags;
+
+ bool mLastJointUpdate;
+ bool mFirstSkinUpdate;
+
+ JointNameSet mJointsFromNode;
+ JointTransformMap mJointTransformMap;
+
+ LLPointer<LLVOAvatar> mPreviewAvatar;
+ LLCachedControl<bool> mImporterDebug;
+};
+
+#endif // LL_LLMODELPREVIEW_H
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 8fc356c928..54409a6994 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -574,6 +574,8 @@ BOOL LLPanelStandStopFlying::postBuild()
//mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE));
mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this));
mStopFlyingButton->setVisible(FALSE);
+
+ gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelStandStopFlying::updatePosition, this));
return TRUE;
}
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 64df449c26..4a8ef53a8b 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -169,6 +169,14 @@ LLMuteList::LLMuteList() :
gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1,
_PREHASH_UseCachedMuteList, processUseCachedMuteList,
static_cast<void**>(NULL)));
+
+ // make sure mute list's instance gets initialized before we start any name requests
+ LLAvatarNameCache::getInstance()->setAccountNameChangedCallback([this](const LLUUID& id, const LLAvatarName& av_name)
+ {
+ // it would be better to just pass LLAvatarName instead of doing unnesssesary copies
+ // but this way is just more convinient
+ onAccountNameChanged(id, av_name.getUserName());
+ });
}
//-----------------------------------------------------------------------------
@@ -179,6 +187,11 @@ LLMuteList::~LLMuteList()
}
+void LLMuteList::cleanupSingleton()
+{
+ LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL);
+}
+
BOOL LLMuteList::isLinden(const std::string& name) const
{
std::string username = boost::replace_all_copy(name, ".", " ");
@@ -232,8 +245,8 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
LL_WARNS() << "Trying to self; ignored" << LL_ENDL;
return FALSE;
}
-
- S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit");
+
+ static LLCachedControl<S32> mute_list_limit(gSavedSettings, "MuteListLimit", 1000);
if (getMutes().size() >= mute_list_limit)
{
LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL;
@@ -358,6 +371,10 @@ void LLMuteList::updateAdd(const LLMute& mute)
msg->addU32("MuteFlags", mute.mFlags);
gAgent.sendReliableMessage();
+ if (!mIsLoaded)
+ {
+ LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;
+ }
mIsLoaded = TRUE; // why is this here? -MG
}
@@ -391,6 +408,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
else
{
// The caller didn't pass any flags -- just remove the mute entry entirely.
+ // set flags to notify observers with (flag being present means that something is allowed)
+ localmute.mFlags = LLMute::flagAll;
}
// Always remove the entry from the set -- it will be re-added with new flags if necessary.
@@ -411,8 +430,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
}
// Must be after erase.
+ notifyObservers();
notifyObserversDetailed(localmute);
- setLoaded(); // why is this here? -MG
}
else
{
@@ -425,8 +444,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
updateRemove(mute);
mLegacyMutes.erase(legacy_it);
// Must be after erase.
+ notifyObservers();
notifyObserversDetailed(mute);
- setLoaded(); // why is this here? -MG
}
}
@@ -584,6 +603,19 @@ BOOL LLMuteList::loadFromFile(const std::string& filename)
}
fclose(fp);
setLoaded();
+
+ // server does not maintain up-to date account names (not display names!)
+ // in this list, so it falls to viewer.
+ pending_names_t::iterator iter = mPendingAgentNameUpdates.begin();
+ pending_names_t::iterator end = mPendingAgentNameUpdates.end();
+ while (iter != end)
+ {
+ // this will send updates to server, make sure mIsLoaded is set
+ onAccountNameChanged(iter->first, iter->second);
+ iter++;
+ }
+ mPendingAgentNameUpdates.clear();
+
return TRUE;
}
@@ -694,7 +726,20 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_MuteData);
msg->addU32Fast(_PREHASH_MuteCRC, crc.getCRC());
- gAgent.sendReliableMessage();
+
+ if (gDisconnected)
+ {
+ LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
+ return;
+ }
+ if (!gAgent.getRegion())
+ {
+ LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
+ return;
+ }
+ // Double amount of retries due to this request happening during busy stage
+ // Ideally this should be turned into a capability
+ gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
}
//-----------------------------------------------------------------------------
@@ -767,6 +812,48 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
delete local_filename_and_path;
}
+void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)
+{
+ if (mIsLoaded)
+ {
+ LLMute mute(id, username, LLMute::AGENT);
+ mute_set_t::iterator mute_it = mMutes.find(mute);
+ if (mute_it != mMutes.end()
+ && mute_it->mName != mute.mName
+ && mute_it->mType == LLMute::AGENT) // just in case, it is std::set, not map
+ {
+ // existing mute, but name changed, copy data
+ mute.mFlags = mute_it->mFlags;
+
+ // erase old variant
+ mMutes.erase(mute_it);
+
+ // (re)add the mute entry.
+ {
+ std::pair<mute_set_t::iterator, bool> result = mMutes.insert(mute);
+ if (result.second)
+ {
+ LL_INFOS() << "Muting " << mute.mName << " id " << mute.mID << " flags " << mute.mFlags << LL_ENDL;
+ updateAdd(mute);
+ // Do not notify observers here, observers do not know or need to handle name changes
+ // Example: block list considers notifyObserversDetailed as a selection update;
+ // Various chat/voice statuses care only about id and flags
+ // Since apropriate update time for account names is considered to be in 'hours' it is
+ // fine not to update UI (will be fine after restart or couple other changes)
+
+ }
+ }
+ }
+ }
+ else
+ {
+ // Delay update until we load file
+ // Ex: Buddies list can arrive too early since we prerequest
+ // names from Buddies list before we load blocklist
+ mPendingAgentNameUpdates[id] = username;
+ }
+}
+
void LLMuteList::addObserver(LLMuteListObserver* observer)
{
mObservers.insert(observer);
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index f2fcf3dbb3..0d426fbd48 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -73,6 +73,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
{
LLSINGLETON(LLMuteList);
~LLMuteList();
+ /*virtual*/ void cleanupSingleton();
public:
// reasons for auto-unmuting a resident
enum EAutoReason
@@ -131,6 +132,7 @@ private:
static void processUseCachedMuteList(LLMessageSystem* msg, void**);
static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status);
+ void onAccountNameChanged(const LLUUID& id, const std::string& username);
private:
struct compare_by_name
@@ -155,7 +157,9 @@ private:
};
typedef std::set<LLMute, compare_by_id> mute_set_t;
mute_set_t mMutes;
-
+ typedef std::map<LLUUID, std::string> pending_names_t;
+ pending_names_t mPendingAgentNameUpdates;
+
typedef std::set<std::string> string_set_t;
string_set_t mLegacyMutes;
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 179c64b5c5..19dbbeb60e 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -58,6 +58,7 @@
#include "llweb.h"
#include "llhints.h"
+#include "llfloatersidepanelcontainer.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
@@ -290,6 +291,7 @@ BOOL LLNavigationBar::postBuild()
mBtnBack = getChild<LLPullButton>("back_btn");
mBtnForward = getChild<LLPullButton>("forward_btn");
mBtnHome = getChild<LLButton>("home_btn");
+ mBtnLandmarks = getChild<LLButton>("landmarks_btn");
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
@@ -305,6 +307,8 @@ BOOL LLNavigationBar::postBuild()
mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
+ mBtnLandmarks->setClickedCallback(boost::bind(&LLNavigationBar::onLandmarksButtonClicked, this));
+
mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
@@ -401,6 +405,12 @@ void LLNavigationBar::onHomeButtonClicked()
gAgent.teleportHome();
}
+void LLNavigationBar::onLandmarksButtonClicked()
+{
+ LLFloaterReg::toggleInstanceOrBringToFront("places");
+ LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_landmark_tab"));
+}
+
void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
{
int idx = userdata.asInteger();
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index a44c6dd699..646911a62c 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -119,6 +119,7 @@ private:
void onNavigationButtonHeldUp(LLButton* nav_button);
void onForwardButtonClicked();
void onHomeButtonClicked();
+ void onLandmarksButtonClicked();
void onLocationSelection();
void onLocationPrearrange(const LLSD& data);
void onTeleportFinished(const LLVector3d& global_agent_pos);
@@ -144,6 +145,7 @@ private:
LLPullButton* mBtnBack;
LLPullButton* mBtnForward;
LLButton* mBtnHome;
+ LLButton* mBtnLandmarks;
LLLocationInputCtrl* mCmbLocation;
LLRect mDefaultNbRect;
LLRect mDefaultFpRect;
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index fc1039b372..112da55682 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -354,7 +354,7 @@ void LLNetMap::draw()
LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color;
- unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z &&
+ unknown_relative_z = positions[i].mdV[VZ] >= COARSEUPDATE_MAX_Z &&
camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
LLWorldMapView::drawAvatar(
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 52c5234137..ef4aced2c7 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -297,6 +297,7 @@ public:
* Writes notification message to IM p2p session.
*/
static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
+ static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false);
/**
* Writes group notice notification message to IM group session.
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 9a3f1a853a..39a0b9b50e 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -123,15 +123,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name
}
// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only)
{
if (!gCacheName)
{
return;
}
- LLUUID from_id = notification->getPayload()["from_id"];
-
if (from_id.isNull())
{
// Normal behavior for system generated messages, don't spam.
@@ -141,15 +139,22 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
if(to_file_only)
{
- LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+ LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID()));
}
else
{
- LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
+ LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id));
}
}
// static
+void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+{
+ LLUUID from_id = notification->getPayload()["from_id"];
+ logToIMP2P(from_id, notification->getMessage(), to_file_only);
+}
+
+// static
void LLHandlerUtil::logGroupNoticeToIMGroup(
const LLNotificationPtr& notification)
{
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 14d25d8158..a9678b1e93 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -37,6 +37,8 @@
#include "llimview.h"
#include "llnotificationsutil.h"
+#include <boost/regex.hpp>
+
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
@@ -143,7 +145,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
{
// log only to file if notif panel can be embedded to IM and IM is opened
bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
- LLHandlerUtil::logToIMP2P(notification, file_only);
+ if ((notification->getName() == "TeleportOffered"
+ || notification->getName() == "TeleportOffered_MaturityExceeded"
+ || notification->getName() == "TeleportOffered_MaturityBlocked"))
+ {
+ boost::regex r("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>( - )?",
+ boost::regex::perl|boost::regex::icase);
+ std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, "");
+ LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only);
+ }
+ else
+ {
+ LLHandlerUtil::logToIMP2P(notification, file_only);
+ }
}
}
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index b2b6de94b3..272e7ae351 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -36,7 +36,7 @@
#include "llaccordionctrltab.h"
#include "llappearancemgr.h"
-#include "lleconomy.h"
+#include "llagentbenefits.h"
#include "llerror.h"
#include "llfilepicker.h"
#include "llfloaterperms.h"
@@ -910,6 +910,7 @@ bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param)
bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param)
{
+ mMenuHandle.get()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
if ("remove_photo" == param)
{
LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
@@ -1046,6 +1047,7 @@ void LLOutfitGallery::updateSnapshotFolderObserver()
void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
{
LLViewerInventoryCategory* category = gInventory.getCategory(category_id);
+ if (category)
{
bool photo_loaded = false;
LLInventoryModel::cat_array_t sub_cat_array;
@@ -1205,7 +1207,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename
return;
}
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
+ S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
void *nruserdata = NULL;
nruserdata = (void *)&outfit_id;
@@ -1215,7 +1217,6 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename
checkRemovePhoto(outfit_id);
std::string upload_pending_name = outfit_id.asString();
std::string upload_pending_desc = "";
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
LLUUID photo_id = upload_new_resource(filename, // file
upload_pending_name,
upload_pending_desc,
@@ -1223,7 +1224,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename
LLFloaterPerms::getNextOwnerPerms("Uploads"),
LLFloaterPerms::getGroupPerms("Uploads"),
LLFloaterPerms::getEveryonePerms("Uploads"),
- upload_pending_name, callback, expected_upload_cost, nruserdata, false);
+ upload_pending_name, LLAssetStorage::LLStoreAssetCallback(), expected_upload_cost, nruserdata, false);
mOutfitLinkPending = outfit_id;
}
delete unit;
@@ -1364,6 +1365,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->setCanApply(false, true);
}
floaterp->openFloater();
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index f2a284a561..71ab826e1c 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -35,6 +35,7 @@
#include "llaccordionctrltab.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llagentbenefits.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
@@ -1235,6 +1236,7 @@ bool LLOutfitListGearMenuBase::onEnable(LLSD::String param)
bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
{
+ getMenu()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
const LLUUID& selected_outfit_id = getSelectedOutfitID();
if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
{
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 7f6c065bb9..7129641c20 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -245,11 +245,11 @@ void LLOutputMonitorCtrl::draw()
// virtual
BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
+ if (mSpeakerId != gAgentID)
{
LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
}
- else if(mShowParticipantsSpeaking)
+ else if (mShowParticipantsSpeaking)
{
LLFloaterReg::showInstance("chat_voice", LLSD());
}
@@ -312,10 +312,14 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
}
}
-void LLOutputMonitorCtrl::onChange()
+void LLOutputMonitorCtrl::onChangeDetailed(const LLMute& mute)
{
- // check only blocking on voice. EXT-3542
- mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
+ if (mute.mID == mSpeakerId)
+ {
+ // Check only blocking on voice.
+ // Logic goes in reverse, if flag is set, action is allowed
+ mIsMuted = !(LLMute::flagVoiceChat & mute.mFlags);
+ }
}
// virtual
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 98966d39ee..e80745e1df 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -105,7 +105,8 @@ public:
void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
//called by mute list
- virtual void onChange();
+ virtual void onChange() {};
+ virtual void onChangeDetailed(const LLMute& mute);
/**
* Implementation of LLSpeakingIndicator interface.
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 5d1b582d1f..37ed4bc74c 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -44,6 +44,7 @@
#include "llavatariconctrl.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
+#include "llviewermenu.h" // is_agent_mappable
#include "llvoiceclient.h"
#include "lltextbox.h"
#include "lltrans.h"
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 6d0c30fbf3..c0342eef4e 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -764,6 +764,7 @@ void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType t
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));
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 451f41cd3b..3bae0cebfb 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -30,7 +30,6 @@
#include "llpanelcontents.h"
// linden library includes
-#include "lleconomy.h"
#include "llerror.h"
#include "llfloaterreg.h"
#include "llfontgl.h"
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
new file mode 100644
index 0000000000..a169712bd8
--- /dev/null
+++ b/indra/newview/llpaneleditsky.cpp
@@ -0,0 +1,976 @@
+/**
+* @file llpaneleditsky.cpp
+* @brief Floaters to create and edit fixed settings for sky and water.
+*
+* $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$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpaneleditsky.h"
+
+#include "llslider.h"
+#include "llsliderctrl.h"
+#include "lltexturectrl.h"
+#include "llcolorswatch.h"
+#include "llvirtualtrackball.h"
+#include "llsettingssky.h"
+#include "llenvironment.h"
+#include "llatmosphere.h"
+
+namespace
+{
+ // Atmosphere Tab
+ const std::string FIELD_SKY_AMBIENT_LIGHT("ambient_light");
+ const std::string FIELD_SKY_BLUE_HORIZON("blue_horizon");
+ const std::string FIELD_SKY_BLUE_DENSITY("blue_density");
+ const std::string FIELD_SKY_HAZE_HORIZON("haze_horizon");
+ const std::string FIELD_SKY_HAZE_DENSITY("haze_density");
+ const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma");
+ const std::string FIELD_SKY_DENSITY_MULTIP("density_multip");
+ const std::string FIELD_SKY_DISTANCE_MULTIP("distance_multip");
+ const std::string FIELD_SKY_MAX_ALT("max_alt");
+
+ const std::string FIELD_SKY_CLOUD_COLOR("cloud_color");
+ const std::string FIELD_SKY_CLOUD_COVERAGE("cloud_coverage");
+ const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale");
+ const std::string FIELD_SKY_CLOUD_VARIANCE("cloud_variance");
+
+ const std::string FIELD_SKY_CLOUD_SCROLL_XY("cloud_scroll_xy");
+ const std::string FIELD_SKY_CLOUD_MAP("cloud_map");
+ const std::string FIELD_SKY_CLOUD_DENSITY_X("cloud_density_x");
+ const std::string FIELD_SKY_CLOUD_DENSITY_Y("cloud_density_y");
+ const std::string FIELD_SKY_CLOUD_DENSITY_D("cloud_density_d");
+ const std::string FIELD_SKY_CLOUD_DETAIL_X("cloud_detail_x");
+ const std::string FIELD_SKY_CLOUD_DETAIL_Y("cloud_detail_y");
+ const std::string FIELD_SKY_CLOUD_DETAIL_D("cloud_detail_d");
+
+ const std::string FIELD_SKY_SUN_MOON_COLOR("sun_moon_color");
+ const std::string FIELD_SKY_GLOW_FOCUS("glow_focus");
+ const std::string FIELD_SKY_GLOW_SIZE("glow_size");
+ const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
+ const std::string FIELD_SKY_SUN_ROTATION("sun_rotation");
+ const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
+ const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");
+ const std::string FIELD_SKY_SUN_IMAGE("sun_image");
+ const std::string FIELD_SKY_SUN_SCALE("sun_scale");
+ const std::string FIELD_SKY_SUN_BEACON("sunbeacon");
+ const std::string FIELD_SKY_MOON_BEACON("moonbeacon");
+ const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
+ const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
+ const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
+ const std::string FIELD_SKY_MOON_IMAGE("moon_image");
+ const std::string FIELD_SKY_MOON_SCALE("moon_scale");
+ const std::string FIELD_SKY_MOON_BRIGHTNESS("moon_brightness");
+
+ const std::string PANEL_SKY_SUN_LAYOUT("sun_layout");
+ const std::string PANEL_SKY_MOON_LAYOUT("moon_layout");
+
+ const std::string FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL("rayleigh_exponential");
+ const std::string FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL_SCALE("rayleigh_exponential_scale");
+ const std::string FIELD_SKY_DENSITY_RAYLEIGH_LINEAR("rayleigh_linear");
+ const std::string FIELD_SKY_DENSITY_RAYLEIGH_CONSTANT("rayleigh_constant");
+ const std::string FIELD_SKY_DENSITY_RAYLEIGH_MAX_ALTITUDE("rayleigh_max_altitude");
+
+ const std::string FIELD_SKY_DENSITY_MIE_EXPONENTIAL("mie_exponential");
+ const std::string FIELD_SKY_DENSITY_MIE_EXPONENTIAL_SCALE("mie_exponential_scale");
+ const std::string FIELD_SKY_DENSITY_MIE_LINEAR("mie_linear");
+ const std::string FIELD_SKY_DENSITY_MIE_CONSTANT("mie_constant");
+ const std::string FIELD_SKY_DENSITY_MIE_ANISO("mie_aniso_factor");
+ const std::string FIELD_SKY_DENSITY_MIE_MAX_ALTITUDE("mie_max_altitude");
+
+ const std::string FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL("absorption_exponential");
+ const std::string FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL_SCALE("absorption_exponential_scale");
+ const std::string FIELD_SKY_DENSITY_ABSORPTION_LINEAR("absorption_linear");
+ const std::string FIELD_SKY_DENSITY_ABSORPTION_CONSTANT("absorption_constant");
+ const std::string FIELD_SKY_DENSITY_ABSORPTION_MAX_ALTITUDE("absorption_max_altitude");
+
+ const std::string FIELD_SKY_DENSITY_MOISTURE_LEVEL("moisture_level");
+ const std::string FIELD_SKY_DENSITY_DROPLET_RADIUS("droplet_radius");
+ const std::string FIELD_SKY_DENSITY_ICE_LEVEL("ice_level");
+
+ 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);
+ const F32 SLIDER_SCALE_GLOW_B(-5.0f);
+ const F32 SLIDER_SCALE_DENSITY_MULTIPLIER(0.001f);
+}
+
+static LLPanelInjector<LLPanelSettingsSkyAtmosTab> t_settings_atmos("panel_settings_atmos");
+static LLPanelInjector<LLPanelSettingsSkyCloudTab> t_settings_cloud("panel_settings_cloud");
+static LLPanelInjector<LLPanelSettingsSkySunMoonTab> t_settings_sunmoon("panel_settings_sunmoon");
+static LLPanelInjector<LLPanelSettingsSkyDensityTab> t_settings_density("panel_settings_density");
+
+//==========================================================================
+LLPanelSettingsSky::LLPanelSettingsSky() :
+ LLSettingsEditPanel(),
+ mSkySettings()
+{
+
+}
+
+
+//==========================================================================
+LLPanelSettingsSkyAtmosTab::LLPanelSettingsSkyAtmosTab() :
+ LLPanelSettingsSky()
+{
+}
+
+
+BOOL LLPanelSettingsSkyAtmosTab::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_AMBIENT_LIGHT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAmbientLightChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_BLUE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueHorizonChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_BLUE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlueDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeHorizonChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onHazeDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSceneGammaChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDensityMultipChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDistanceMultipChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMaxAltChanged(); });
+ 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(); });
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+
+ // Make sure we have initialized children (initialized)
+ if (getFirstChild())
+ {
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setEnabled(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);
+ }
+}
+
+void LLPanelSettingsSkyAtmosTab::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(getCanChangeSettings());
+ setAllChildrenEnabled(getCanChangeSettings());
+
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->set(mSkySettings->getAmbientColor() / SLIDER_SCALE_SUN_AMBIENT);
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->set(mSkySettings->getBlueHorizon() / SLIDER_SCALE_BLUE_HORIZON_DENSITY);
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->set(mSkySettings->getBlueDensity() / SLIDER_SCALE_BLUE_HORIZON_DENSITY);
+
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->setValue(mSkySettings->getHazeHorizon());
+ getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->setValue(mSkySettings->getHazeDensity());
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setValue(mSkySettings->getGamma());
+ F32 density_mult = mSkySettings->getDensityMultiplier();
+ density_mult /= SLIDER_SCALE_DENSITY_MULTIPLIER;
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->setValue(density_mult);
+ getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->setValue(mSkySettings->getDistanceMultiplier());
+ getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->setValue(mSkySettings->getMaxY());
+
+ F32 moisture_level = mSkySettings->getSkyMoistureLevel();
+ F32 droplet_radius = mSkySettings->getSkyDropletRadius();
+ F32 ice_level = mSkySettings->getSkyIceLevel();
+
+ 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);
+}
+
+//-------------------------------------------------------------------------
+void LLPanelSettingsSkyAtmosTab::onAmbientLightChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setAmbientColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_AMBIENT_LIGHT)->get() * SLIDER_SCALE_SUN_AMBIENT));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onBlueHorizonChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setBlueHorizon(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_HORIZON)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onBlueDensityChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setBlueDensity(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_BLUE_DENSITY)->get() * SLIDER_SCALE_BLUE_HORIZON_DENSITY));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onHazeHorizonChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setHazeHorizon(getChild<LLUICtrl>(FIELD_SKY_HAZE_HORIZON)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onHazeDensityChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setHazeDensity(getChild<LLUICtrl>(FIELD_SKY_HAZE_DENSITY)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onSceneGammaChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setGamma(getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onDensityMultipChanged()
+{
+ if (!mSkySettings) return;
+ F32 density_mult = getChild<LLUICtrl>(FIELD_SKY_DENSITY_MULTIP)->getValue().asReal();
+ density_mult *= SLIDER_SCALE_DENSITY_MULTIPLIER;
+ mSkySettings->setDensityMultiplier(density_mult);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onDistanceMultipChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setDistanceMultiplier(getChild<LLUICtrl>(FIELD_SKY_DISTANCE_MULTIP)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onMaxAltChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setMaxY(getChild<LLUICtrl>(FIELD_SKY_MAX_ALT)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onMoistureLevelChanged()
+{
+ if (!mSkySettings) return;
+ F32 moisture_level = getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->getValue().asReal();
+ mSkySettings->setSkyMoistureLevel(moisture_level);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onDropletRadiusChanged()
+{
+ if (!mSkySettings) return;
+ F32 droplet_radius = getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->getValue().asReal();
+ mSkySettings->setSkyDropletRadius(droplet_radius);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyAtmosTab::onIceLevelChanged()
+{
+ if (!mSkySettings) return;
+ F32 ice_level = getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->getValue().asReal();
+ mSkySettings->setSkyIceLevel(ice_level);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+//==========================================================================
+LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() :
+ LLPanelSettingsSky()
+{
+}
+
+BOOL LLPanelSettingsSkyCloudTab::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudColorChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudCoverageChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_VARIANCE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudVarianceChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudScrollChanged(); });
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); });
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setDefaultImageAssetID(LLSettingsSky::GetDefaultCloudNoiseTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setAllowNoTexture(TRUE);
+
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDensityChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudDetailChanged(); });
+
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsSkyCloudTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+
+ // Make sure we have children (initialized)
+ if (getFirstChild())
+ {
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_VARIANCE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->setEnabled(enabled);
+ }
+}
+
+void LLPanelSettingsSkyCloudTab::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(getCanChangeSettings());
+ setAllChildrenEnabled(getCanChangeSettings());
+
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->set(mSkySettings->getCloudColor());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->setValue(mSkySettings->getCloudShadow());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->setValue(mSkySettings->getCloudScale());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_VARIANCE)->setValue(mSkySettings->getCloudVariance());
+
+ LLVector2 cloudScroll(mSkySettings->getCloudScrollRate());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_XY)->setValue(cloudScroll.getValue());
+
+ getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mSkySettings->getCloudNoiseTextureId());
+
+ LLVector3 cloudDensity(mSkySettings->getCloudPosDensity1().getValue());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->setValue(cloudDensity[0]);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->setValue(cloudDensity[1]);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->setValue(cloudDensity[2]);
+
+ LLVector3 cloudDetail(mSkySettings->getCloudPosDensity2().getValue());
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->setValue(cloudDetail[0]);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->setValue(cloudDetail[1]);
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->setValue(cloudDetail[2]);
+}
+
+//-------------------------------------------------------------------------
+void LLPanelSettingsSkyCloudTab::onCloudColorChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setCloudColor(LLColor3(getChild<LLColorSwatchCtrl>(FIELD_SKY_CLOUD_COLOR)->get()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudCoverageChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setCloudShadow(getChild<LLUICtrl>(FIELD_SKY_CLOUD_COVERAGE)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudScaleChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setCloudScale(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCALE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudVarianceChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setCloudVariance(getChild<LLUICtrl>(FIELD_SKY_CLOUD_VARIANCE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudScrollChanged()
+{
+ if (!mSkySettings) return;
+ LLVector2 scroll(getChild<LLUICtrl>(FIELD_SKY_CLOUD_SCROLL_XY)->getValue());
+ mSkySettings->setCloudScrollRate(scroll);
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudMapChanged()
+{
+ if (!mSkySettings) return;
+ LLTextureCtrl* ctrl = getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP);
+ mSkySettings->setCloudNoiseTextureId(ctrl->getValue().asUUID());
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudDensityChanged()
+{
+ if (!mSkySettings) return;
+ LLColor3 density(getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_X)->getValue().asReal(),
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_Y)->getValue().asReal(),
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DENSITY_D)->getValue().asReal());
+
+ mSkySettings->setCloudPosDensity1(density);
+ setIsDirty();
+}
+
+void LLPanelSettingsSkyCloudTab::onCloudDetailChanged()
+{
+ if (!mSkySettings) return;
+ LLColor3 detail(getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_X)->getValue().asReal(),
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_Y)->getValue().asReal(),
+ getChild<LLUICtrl>(FIELD_SKY_CLOUD_DETAIL_D)->getValue().asReal());
+
+ mSkySettings->setCloudPosDensity2(detail);
+ setIsDirty();
+}
+
+//==========================================================================
+LLPanelSettingsSkySunMoonTab::LLPanelSettingsSkySunMoonTab() :
+ LLPanelSettingsSky()
+{
+}
+
+
+BOOL LLPanelSettingsSkySunMoonTab::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_SUN_MOON_COLOR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunMoonColorChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
+ getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetBlankSunTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetBlankSunTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowNoTexture(TRUE);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); });
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setAllowNoTexture(TRUE);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonBrightnessChanged(); });
+
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsSkySunMoonTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+
+ // Make sure we have children
+ if (getFirstChild())
+ {
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setEnabled(enabled);
+ getChildView(PANEL_SKY_SUN_LAYOUT)->setAllChildrenEnabled(TRUE);
+ getChildView(PANEL_SKY_MOON_LAYOUT)->setAllChildrenEnabled(TRUE);
+ }
+}
+
+void LLPanelSettingsSkySunMoonTab::refresh()
+{
+ if (!mSkySettings || !getCanChangeSettings())
+ {
+ getChildView(PANEL_SKY_SUN_LAYOUT)->setAllChildrenEnabled(FALSE);
+ getChildView(PANEL_SKY_MOON_LAYOUT)->setAllChildrenEnabled(FALSE);
+ getChildView(FIELD_SKY_SUN_BEACON)->setEnabled(TRUE);
+ getChildView(FIELD_SKY_MOON_BEACON)->setEnabled(TRUE);
+
+ if (!mSkySettings)
+ return;
+ }
+ else
+ {
+ setEnabled(TRUE);
+ setAllChildrenEnabled(TRUE);
+ }
+
+ getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->set(mSkySettings->getSunlightColor() / SLIDER_SCALE_SUN_AMBIENT);
+
+ LLColor3 glow(mSkySettings->getGlow());
+
+ // takes 40 - 0.2 range -> 0 - 1.99 UI range
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R));
+ getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
+
+ getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness());
+ getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId());
+ getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale());
+ getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId());
+ getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale());
+ getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setValue(mSkySettings->getMoonBrightness());
+
+ // Sun rotation values
+ F32 azimuth, elevation;
+ LLQuaternion quat = mSkySettings->getSunRotation();
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+
+ // Moon rotation values
+ quat = mSkySettings->getMoonRotation();
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+
+}
+
+//-------------------------------------------------------------------------
+void LLPanelSettingsSkySunMoonTab::onSunMoonColorChanged()
+{
+ if (!mSkySettings) return;
+ LLColor3 color(getChild<LLColorSwatchCtrl>(FIELD_SKY_SUN_MOON_COLOR)->get());
+
+ color *= SLIDER_SCALE_SUN_AMBIENT;
+
+ mSkySettings->setSunlightColor(color);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onGlowChanged()
+{
+ if (!mSkySettings) return;
+ LLColor3 glow(getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->getValue().asReal(), 0.0f, getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->getValue().asReal());
+
+ // takes 0 - 1.99 UI range -> 40 -> 0.2 range
+ glow.mV[0] = (2.0f - glow.mV[0]) * SLIDER_SCALE_GLOW_R;
+ glow.mV[2] *= SLIDER_SCALE_GLOW_B;
+
+ mSkySettings->setGlow(glow);
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setStarBrightness(getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->getValue().asReal());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunRotationChanged()
+{
+ LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
+
+ F32 azimuth, elevation;
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+ if (mSkySettings)
+ {
+ mSkySettings->setSunRotation(quat);
+ mSkySettings->update();
+ setIsDirty();
+ }
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunAzimElevChanged()
+{
+ F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
+ F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
+ LLQuaternion quat;
+
+ azimuth *= DEG_TO_RAD;
+ elevation *= DEG_TO_RAD;
+
+ if (is_approx_zero(elevation))
+ {
+ elevation = F_APPROXIMATELY_ZERO;
+ }
+
+ quat.setAngleAxis(-elevation, 0, 1, 0);
+ LLQuaternion az_quat;
+ az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+ quat *= az_quat;
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+ if (mSkySettings)
+ {
+ mSkySettings->setSunRotation(quat);
+ mSkySettings->update();
+ setIsDirty();
+ }
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunScaleChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setSunScale((getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->getValue().asReal()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunImageChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setSunTextureId(getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->getValue().asUUID());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged()
+{
+ LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
+
+ F32 azimuth, elevation;
+ LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+ getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+
+ if (mSkySettings)
+ {
+ mSkySettings->setMoonRotation(quat);
+ mSkySettings->update();
+ setIsDirty();
+ }
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonAzimElevChanged()
+{
+ F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
+ F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
+ LLQuaternion quat;
+
+ azimuth *= DEG_TO_RAD;
+ elevation *= DEG_TO_RAD;
+
+ if (is_approx_zero(elevation))
+ {
+ elevation = F_APPROXIMATELY_ZERO;
+ }
+
+ quat.setAngleAxis(-elevation, 0, 1, 0);
+ LLQuaternion az_quat;
+ az_quat.setAngleAxis(F_TWO_PI- azimuth, 0, 0, 1);
+ quat *= az_quat;
+
+ getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+
+ if (mSkySettings)
+ {
+ mSkySettings->setMoonRotation(quat);
+ mSkySettings->update();
+ setIsDirty();
+ }
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonImageChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setMoonTextureId(getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->getValue().asUUID());
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonScaleChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setMoonScale((getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->getValue().asReal()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonBrightnessChanged()
+{
+ if (!mSkySettings) return;
+ mSkySettings->setMoonBrightness((getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->getValue().asReal()));
+ mSkySettings->update();
+ setIsDirty();
+}
+
+LLPanelSettingsSkyDensityTab::LLPanelSettingsSkyDensityTab()
+{
+}
+
+BOOL LLPanelSettingsSkyDensityTab::postBuild()
+{
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onRayleighExponentialChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onRayleighExponentialScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_LINEAR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onRayleighLinearChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_CONSTANT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onRayleighConstantChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_MAX_ALTITUDE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onRayleighMaxAltitudeChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieExponentialChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieExponentialScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_LINEAR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieLinearChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_CONSTANT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieConstantChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_ANISO)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieAnisoFactorChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_MAX_ALTITUDE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMieMaxAltitudeChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAbsorptionExponentialChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAbsorptionExponentialScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_LINEAR)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAbsorptionLinearChanged(); });
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_CONSTANT)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAbsorptionConstantChanged(); });
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_MAX_ALTITUDE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onAbsorptionMaxAltitudeChanged(); });
+
+ refresh();
+ return TRUE;
+}
+
+void LLPanelSettingsSkyDensityTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsSky::setEnabled(enabled);
+
+ // Make sure we have children
+ if (getFirstChild())
+ {
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_LINEAR)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_CONSTANT)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_MAX_ALTITUDE)->setEnabled(enabled);
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_LINEAR)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_CONSTANT)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_ANISO)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_MAX_ALTITUDE)->setEnabled(enabled);
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_LINEAR)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_CONSTANT)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_MAX_ALTITUDE)->setEnabled(enabled);
+ }
+}
+
+void LLPanelSettingsSkyDensityTab::refresh()
+{
+ if (!mSkySettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(getCanChangeSettings());
+ setAllChildrenEnabled(getCanChangeSettings());
+
+ // Get first (only) profile layer of each type for editing
+ LLSD rayleigh_config = mSkySettings->getRayleighConfig();
+ LLSD mie_config = mSkySettings->getMieConfig();
+ LLSD absorption_config = mSkySettings->getAbsorptionConfig();
+
+ F32 rayleigh_exponential_term = rayleigh_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ F32 rayleigh_exponential_scale = rayleigh_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ F32 rayleigh_linear_term = rayleigh_config[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ F32 rayleigh_constant_term = rayleigh_config[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ F32 rayleigh_max_alt = rayleigh_config[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+
+ F32 mie_exponential_term = mie_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ F32 mie_exponential_scale = mie_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ F32 mie_linear_term = mie_config[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ F32 mie_constant_term = mie_config[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal();
+ F32 mie_aniso_factor = mie_config[LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR].asReal();
+ F32 mie_max_alt = mie_config[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+
+ F32 absorption_exponential_term = absorption_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ F32 absorption_exponential_scale = absorption_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal();
+ F32 absorption_linear_term = absorption_config[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal();
+ F32 absorption_constant_term = absorption_config[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal();
+ F32 absorption_max_alt = absorption_config[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal();
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL)->setValue(rayleigh_exponential_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL_SCALE)->setValue(rayleigh_exponential_scale);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_LINEAR)->setValue(rayleigh_linear_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_CONSTANT)->setValue(rayleigh_constant_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_RAYLEIGH_MAX_ALTITUDE)->setValue(rayleigh_max_alt);
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL)->setValue(mie_exponential_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL_SCALE)->setValue(mie_exponential_scale);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_LINEAR)->setValue(mie_linear_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_CONSTANT)->setValue(mie_constant_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_ANISO)->setValue(mie_aniso_factor);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_MIE_MAX_ALTITUDE)->setValue(mie_max_alt);
+
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL)->setValue(absorption_exponential_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL_SCALE)->setValue(absorption_exponential_scale);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_LINEAR)->setValue(absorption_linear_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_CONSTANT)->setValue(absorption_constant_term);
+ getChild<LLUICtrl>(FIELD_SKY_DENSITY_ABSORPTION_MAX_ALTITUDE)->setValue(absorption_max_alt);
+}
+
+void LLPanelSettingsSkyDensityTab::updateProfile()
+{
+ F32 rayleigh_exponential_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL)->getValueF32();
+ F32 rayleigh_exponential_scale = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_RAYLEIGH_EXPONENTIAL_SCALE)->getValueF32();
+ F32 rayleigh_linear_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_RAYLEIGH_LINEAR)->getValueF32();
+ F32 rayleigh_constant_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_RAYLEIGH_CONSTANT)->getValueF32();
+ F32 rayleigh_max_alt = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_RAYLEIGH_MAX_ALTITUDE)->getValueF32();
+
+ F32 mie_exponential_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL)->getValueF32();
+ F32 mie_exponential_scale = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_EXPONENTIAL_SCALE)->getValueF32();
+ F32 mie_linear_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_LINEAR)->getValueF32();
+ F32 mie_constant_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_CONSTANT)->getValueF32();
+ F32 mie_aniso_factor = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_ANISO)->getValueF32();
+ F32 mie_max_alt = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_MIE_MAX_ALTITUDE)->getValueF32();
+
+ F32 absorption_exponential_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL)->getValueF32();
+ F32 absorption_exponential_scale = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ABSORPTION_EXPONENTIAL_SCALE)->getValueF32();
+ F32 absorption_linear_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ABSORPTION_LINEAR)->getValueF32();
+ F32 absorption_constant_term = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ABSORPTION_CONSTANT)->getValueF32();
+ F32 absorption_max_alt = getChild<LLSliderCtrl>(FIELD_SKY_DENSITY_ABSORPTION_MAX_ALTITUDE)->getValueF32();
+
+ LLSD rayleigh_config = LLSettingsSky::createSingleLayerDensityProfile(rayleigh_max_alt, rayleigh_exponential_term, rayleigh_exponential_scale, rayleigh_linear_term, rayleigh_constant_term);
+ LLSD mie_config = LLSettingsSky::createSingleLayerDensityProfile(mie_max_alt, mie_exponential_term, mie_exponential_scale, mie_linear_term, mie_constant_term, mie_aniso_factor);
+ LLSD absorption_layer = LLSettingsSky::createSingleLayerDensityProfile(absorption_max_alt, absorption_exponential_term, absorption_exponential_scale, absorption_linear_term, absorption_constant_term);
+
+ static LLSD absorption_layer_ozone = LLSettingsSky::createDensityProfileLayer(0.0f, 0.0f, 0.0f, -1.0f / 15000.0f, 8.0f / 3.0f);
+
+ LLSD absorption_config;
+ absorption_config.append(absorption_layer);
+ absorption_config.append(absorption_layer_ozone);
+
+ mSkySettings->setRayleighConfigs(rayleigh_config);
+ mSkySettings->setMieConfigs(mie_config);
+ mSkySettings->setAbsorptionConfigs(absorption_config);
+ mSkySettings->update();
+ setIsDirty();
+
+ if (gAtmosphere)
+ {
+ AtmosphericModelSettings atmospheric_settings;
+ LLEnvironment::getAtmosphericModelSettings(atmospheric_settings, mSkySettings);
+ gAtmosphere->configureAtmosphericModel(atmospheric_settings);
+ }
+}
+
+void LLPanelSettingsSkyDensityTab::onRayleighExponentialChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onRayleighExponentialScaleChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onRayleighLinearChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onRayleighConstantChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onRayleighMaxAltitudeChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieExponentialChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieExponentialScaleChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieLinearChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieConstantChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieAnisoFactorChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onMieMaxAltitudeChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onAbsorptionExponentialChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onAbsorptionExponentialScaleChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onAbsorptionLinearChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onAbsorptionConstantChanged()
+{
+ updateProfile();
+}
+
+void LLPanelSettingsSkyDensityTab::onAbsorptionMaxAltitudeChanged()
+{
+ updateProfile();
+}
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
new file mode 100644
index 0000000000..cb63d40b0c
--- /dev/null
+++ b/indra/newview/llpaneleditsky.h
@@ -0,0 +1,173 @@
+/**
+* @file llpaneleditsky.h
+* @brief Panels for sky settings
+*
+* $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$
+*/
+
+#ifndef LLPANEL_EDIT_SKY_H
+#define LLPANEL_EDIT_SKY_H
+
+#include "llpanel.h"
+#include "llsettingssky.h"
+#include "llfloatereditenvironmentbase.h"
+
+//=========================================================================
+class LLSlider;
+class LLColorSwatchCtrl;
+class LLTextureCtrl;
+
+//=========================================================================
+class LLPanelSettingsSky : public LLSettingsEditPanel
+{
+ LOG_CLASS(LLPanelSettingsSky);
+
+public:
+ LLPanelSettingsSky();
+
+ virtual void setSettings(const LLSettingsBase::ptr_t &settings) override { setSky(std::static_pointer_cast<LLSettingsSky>(settings)); }
+
+ LLSettingsSky::ptr_t getSky() const { return mSkySettings; }
+ void setSky(const LLSettingsSky::ptr_t &sky) { mSkySettings = sky; clearIsDirty(); refresh(); }
+
+protected:
+ LLSettingsSky::ptr_t mSkySettings;
+};
+
+class LLPanelSettingsSkyAtmosTab : public LLPanelSettingsSky
+{
+ LOG_CLASS(LLPanelSettingsSkyAtmosTab);
+
+public:
+ LLPanelSettingsSkyAtmosTab();
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+protected:
+ virtual void refresh() override;
+
+private:
+ void onAmbientLightChanged();
+ void onBlueHorizonChanged();
+ void onBlueDensityChanged();
+ void onHazeHorizonChanged();
+ void onHazeDensityChanged();
+ void onSceneGammaChanged();
+ void onDensityMultipChanged();
+ void onDistanceMultipChanged();
+ void onMaxAltChanged();
+ void onMoistureLevelChanged();
+ void onDropletRadiusChanged();
+ void onIceLevelChanged();
+
+};
+
+class LLPanelSettingsSkyCloudTab : public LLPanelSettingsSky
+{
+ LOG_CLASS(LLPanelSettingsSkyCloudTab);
+
+public:
+ LLPanelSettingsSkyCloudTab();
+
+ virtual BOOL postBuild() override;
+ void setEnabled(BOOL enabled) override;
+
+protected:
+ virtual void refresh() override;
+
+private:
+ void onCloudColorChanged();
+ void onCloudCoverageChanged();
+ void onCloudScaleChanged();
+ void onCloudVarianceChanged();
+ void onCloudScrollChanged();
+ void onCloudMapChanged();
+ void onCloudDensityChanged();
+ void onCloudDetailChanged();
+};
+
+class LLPanelSettingsSkySunMoonTab : public LLPanelSettingsSky
+{
+ LOG_CLASS(LLPanelSettingsSkySunMoonTab);
+
+public:
+ LLPanelSettingsSkySunMoonTab();
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+protected:
+ virtual void refresh() override;
+
+private:
+ void onSunMoonColorChanged();
+ void onGlowChanged();
+ void onStarBrightnessChanged();
+ void onSunRotationChanged();
+ void onSunAzimElevChanged();
+ void onSunScaleChanged();
+ void onSunImageChanged();
+ void onMoonRotationChanged();
+ void onMoonAzimElevChanged();
+ void onMoonScaleChanged();
+ void onMoonBrightnessChanged();
+ void onMoonImageChanged();
+};
+
+// single subtab of the density settings tab
+class LLPanelSettingsSkyDensityTab : public LLPanelSettingsSky
+{
+ LOG_CLASS(LLPanelSettingsSkyDensityTab);
+
+public:
+ LLPanelSettingsSkyDensityTab();
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+protected:
+ virtual void refresh() override;
+
+ void onRayleighExponentialChanged();
+ void onRayleighExponentialScaleChanged();
+ void onRayleighLinearChanged();
+ void onRayleighConstantChanged();
+ void onRayleighMaxAltitudeChanged();
+
+ void onMieExponentialChanged();
+ void onMieExponentialScaleChanged();
+ void onMieLinearChanged();
+ void onMieConstantChanged();
+ void onMieAnisoFactorChanged();
+ void onMieMaxAltitudeChanged();
+
+ void onAbsorptionExponentialChanged();
+ void onAbsorptionExponentialScaleChanged();
+ void onAbsorptionLinearChanged();
+ void onAbsorptionConstantChanged();
+ void onAbsorptionMaxAltitudeChanged();
+
+ // update the settings for our profile type
+ void updateProfile();
+};
+#endif // LLPANEL_EDIT_SKY_H
diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp
new file mode 100644
index 0000000000..a09964e17d
--- /dev/null
+++ b/indra/newview/llpaneleditwater.cpp
@@ -0,0 +1,251 @@
+/**
+* @file llpaneleditwater.cpp
+* @brief Floaters to create and edit fixed settings for sky and water.
+*
+* $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$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpaneleditwater.h"
+
+#include "llslider.h"
+#include "lltexturectrl.h"
+#include "llcolorswatch.h"
+#include "llxyvector.h"
+#include "llviewercontrol.h"
+
+namespace
+{
+ const std::string FIELD_WATER_FOG_COLOR("water_fog_color");
+ const std::string FIELD_WATER_FOG_DENSITY("water_fog_density");
+ const std::string FIELD_WATER_UNDERWATER_MOD("water_underwater_mod");
+ const std::string FIELD_WATER_NORMAL_MAP("water_normal_map");
+
+ const std::string FIELD_WATER_WAVE1_XY("water_wave1_xy");
+ const std::string FIELD_WATER_WAVE2_XY("water_wave2_xy");
+
+ const std::string FIELD_WATER_NORMAL_SCALE_X("water_normal_scale_x");
+ const std::string FIELD_WATER_NORMAL_SCALE_Y("water_normal_scale_y");
+ const std::string FIELD_WATER_NORMAL_SCALE_Z("water_normal_scale_z");
+
+ const std::string FIELD_WATER_FRESNEL_SCALE("water_fresnel_scale");
+ const std::string FIELD_WATER_FRESNEL_OFFSET("water_fresnel_offset");
+
+ const std::string FIELD_WATER_SCALE_ABOVE("water_scale_above");
+ const std::string FIELD_WATER_SCALE_BELOW("water_scale_below");
+ const std::string FIELD_WATER_BLUR_MULTIP("water_blur_multip");
+}
+
+static LLPanelInjector<LLPanelSettingsWaterMainTab> t_settings_water("panel_settings_water");
+
+//==========================================================================
+LLPanelSettingsWater::LLPanelSettingsWater() :
+ LLSettingsEditPanel(),
+ mWaterSettings()
+{
+
+}
+
+
+//==========================================================================
+LLPanelSettingsWaterMainTab::LLPanelSettingsWaterMainTab():
+ LLPanelSettingsWater(),
+ mClrFogColor(nullptr),
+ mTxtNormalMap(nullptr)
+{
+}
+
+
+BOOL LLPanelSettingsWaterMainTab::postBuild()
+{
+ mClrFogColor = getChild<LLColorSwatchCtrl>(FIELD_WATER_FOG_COLOR);
+ mTxtNormalMap = getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP);
+
+ getChild<LLXYVector>(FIELD_WATER_WAVE1_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLargeWaveChanged(); });
+
+ mClrFogColor->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogColorChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogDensityChanged(); });
+// getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogDensityChanged(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal()); });
+ getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogUnderWaterChanged(); });
+
+ mTxtNormalMap->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId());
+ mTxtNormalMap->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
+ mTxtNormalMap->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalMapChanged(); });
+
+ getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); });
+
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalScaleChanged(); });
+
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFresnelScaleChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFresnelOffsetChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onScaleAboveChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onScaleBelowChanged(); });
+ getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onBlurMultipChanged(); });
+
+ refresh();
+
+ return TRUE;
+}
+
+//virtual
+void LLPanelSettingsWaterMainTab::setEnabled(BOOL enabled)
+{
+ LLPanelSettingsWater::setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->setEnabled(enabled);
+
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->setEnabled(enabled);
+
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->setEnabled(enabled);
+}
+
+//==========================================================================
+void LLPanelSettingsWaterMainTab::refresh()
+{
+ if (!mWaterSettings)
+ {
+ setAllChildrenEnabled(FALSE);
+ setEnabled(FALSE);
+ return;
+ }
+
+ setEnabled(getCanChangeSettings());
+ setAllChildrenEnabled(getCanChangeSettings());
+ mClrFogColor->set(mWaterSettings->getWaterFogColor());
+ getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->setValue(mWaterSettings->getWaterFogDensity());
+ getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setValue(mWaterSettings->getFogMod());
+ mTxtNormalMap->setValue(mWaterSettings->getNormalMapID());
+ LLVector2 vect2 = mWaterSettings->getWave1Dir() * -1.0; // Flip so that north and east are +
+ getChild<LLUICtrl>(FIELD_WATER_WAVE1_XY)->setValue(vect2.getValue());
+ vect2 = mWaterSettings->getWave2Dir() * -1.0; // Flip so that north and east are +
+ getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->setValue(vect2.getValue());
+ LLVector3 vect3 = mWaterSettings->getNormalScale();
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->setValue(vect3[0]);
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->setValue(vect3[1]);
+ getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->setValue(vect3[2]);
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->setValue(mWaterSettings->getFresnelScale());
+ getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->setValue(mWaterSettings->getFresnelOffset());
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->setValue(mWaterSettings->getScaleAbove());
+ getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->setValue(mWaterSettings->getScaleBelow());
+ getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->setValue(mWaterSettings->getBlurMultiplier());
+}
+
+//==========================================================================
+
+void LLPanelSettingsWaterMainTab::onFogColorChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setWaterFogColor(LLColor3(mClrFogColor->get()));
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFogDensityChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setWaterFogDensity(getChild<LLUICtrl>(FIELD_WATER_FOG_DENSITY)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFogUnderWaterChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setFogMod(getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onNormalMapChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setNormalMapID(mTxtNormalMap->getImageAssetID());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onLargeWaveChanged()
+{
+ if (!mWaterSettings) return;
+ LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE1_XY)->getValue());
+ vect *= -1.0; // Flip so that north and east are -
+ mWaterSettings->setWave1Dir(vect);
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onSmallWaveChanged()
+{
+ if (!mWaterSettings) return;
+ LLVector2 vect(getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->getValue());
+ vect *= -1.0; // Flip so that north and east are -
+ mWaterSettings->setWave2Dir(vect);
+ setIsDirty();
+}
+
+
+void LLPanelSettingsWaterMainTab::onNormalScaleChanged()
+{
+ if (!mWaterSettings) return;
+ LLVector3 vect(getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_X)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Y)->getValue().asReal(), getChild<LLUICtrl>(FIELD_WATER_NORMAL_SCALE_Z)->getValue().asReal());
+ mWaterSettings->setNormalScale(vect);
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFresnelScaleChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setFresnelScale(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_SCALE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onFresnelOffsetChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setFresnelOffset(getChild<LLUICtrl>(FIELD_WATER_FRESNEL_OFFSET)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onScaleAboveChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setScaleAbove(getChild<LLUICtrl>(FIELD_WATER_SCALE_ABOVE)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onScaleBelowChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setScaleBelow(getChild<LLUICtrl>(FIELD_WATER_SCALE_BELOW)->getValue().asReal());
+ setIsDirty();
+}
+
+void LLPanelSettingsWaterMainTab::onBlurMultipChanged()
+{
+ if (!mWaterSettings) return;
+ mWaterSettings->setBlurMultiplier(getChild<LLUICtrl>(FIELD_WATER_BLUR_MULTIP)->getValue().asReal());
+ setIsDirty();
+}
diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h
new file mode 100644
index 0000000000..4b7ec903c9
--- /dev/null
+++ b/indra/newview/llpaneleditwater.h
@@ -0,0 +1,98 @@
+/**
+* @file llpaneleditwater.h
+* @brief Panels for water settings
+*
+* $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$
+*/
+
+#ifndef LLPANEL_EDIT_WATER_H
+#define LLPANEL_EDIT_WATER_H
+
+#include "llpanel.h"
+#include "llsettingswater.h"
+
+#include "llfloatereditenvironmentbase.h"
+
+//=========================================================================
+class LLSlider;
+class LLColorSwatchCtrl;
+class LLTextureCtrl;
+class LLXYVector;
+
+//=========================================================================
+class LLPanelSettingsWater : public LLSettingsEditPanel
+{
+ LOG_CLASS(LLPanelSettingsWater);
+
+public:
+ LLPanelSettingsWater();
+
+ virtual void setSettings(const LLSettingsBase::ptr_t &settings) override { setWater(std::static_pointer_cast<LLSettingsWater>(settings)); }
+
+ LLSettingsWater::ptr_t getWater() const { return mWaterSettings; }
+ void setWater(const LLSettingsWater::ptr_t &water) { mWaterSettings = water; clearIsDirty(); refresh(); }
+
+protected:
+ LLSettingsWater::ptr_t mWaterSettings;
+};
+
+// *RIDER* In this case this split is unecessary since there is only a single
+// tab page for water settings at this point. However more may be added in the
+// future and I want to reinforce the pattern used for sky/atmosphere tabs.
+class LLPanelSettingsWaterMainTab : public LLPanelSettingsWater
+{
+ LOG_CLASS(LLPanelSettingsWaterMainTab);
+
+public:
+ LLPanelSettingsWaterMainTab();
+
+ virtual BOOL postBuild() override;
+ virtual void setEnabled(BOOL enabled) override;
+
+protected:
+ virtual void refresh() override;
+
+private:
+
+ LLColorSwatchCtrl * mClrFogColor;
+// LLSlider * mSldFogDensity;
+// LLSlider * mSldUnderWaterMod;
+ LLTextureCtrl * mTxtNormalMap;
+
+ void onFogColorChanged();
+ void onFogDensityChanged();
+ void onFogUnderWaterChanged();
+ void onNormalMapChanged();
+
+ void onLargeWaveChanged();
+ void onSmallWaveChanged();
+
+ void onNormalScaleChanged();
+ void onFresnelScaleChanged();
+ void onFresnelOffsetChanged();
+ void onScaleAboveChanged();
+ void onScaleBelowChanged();
+ void onBlurMultipChanged();
+};
+
+
+#endif // LLPANEL_EDIT_WATER_H
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6573be0aaf..c601a6c210 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -778,7 +778,7 @@ BOOL LLPanelEditWearable::postBuild()
LL_WARNS() << "could not get wearable dictionary entry for wearable of type: " << type << LL_ENDL;
continue;
}
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
for (U8 index = 0; index < num_subparts; ++index)
{
@@ -1181,7 +1181,7 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
updatePanelPickerControls(type);
// clear and rebuild visual param list
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
for (U8 index = 0; index < num_subparts; ++index)
{
@@ -1372,7 +1372,7 @@ void LLPanelEditWearable::updateScrollingPanelUI()
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
llassert(wearable_entry);
if (!wearable_entry) return;
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
LLScrollingPanelParam::sUpdateDelayFrames = 0;
for (U8 index = 0; index < num_subparts; ++index)
diff --git a/indra/newview/llpanelenvironment.cpp b/indra/newview/llpanelenvironment.cpp
new file mode 100644
index 0000000000..2ad7a23278
--- /dev/null
+++ b/indra/newview/llpanelenvironment.cpp
@@ -0,0 +1,1178 @@
+/**
+ * @file llpanelenvironment.cpp
+ * @brief LLPanelExperiences class implementation
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "llpanelprofile.h"
+#include "lluictrlfactory.h"
+#include "llexperiencecache.h"
+#include "llagent.h"
+#include "llparcel.h"
+
+#include "llviewerregion.h"
+#include "llpanelenvironment.h"
+#include "llslurl.h"
+#include "lllayoutstack.h"
+
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "llfloatereditextdaycycle.h"
+#include "llmultisliderctrl.h"
+#include "llnotificationsutil.h"
+#include "llsettingsvo.h"
+
+#include "llappviewer.h"
+#include "llcallbacklist.h"
+#include "llviewerparcelmgr.h"
+
+#include "llinventorymodel.h"
+
+//=========================================================================
+namespace
+{
+ const std::string FLOATER_DAY_CYCLE_EDIT("env_edit_extdaycycle");
+ const std::string STRING_REGION_ENV("str_region_env");
+ const std::string STRING_EMPTY_NAME("str_empty");
+
+ inline bool ends_with(std::string const & value, std::string const & ending)
+ {
+ if (ending.size() > value.size())
+ return false;
+ return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
+ }
+
+}
+
+//=========================================================================
+const std::string LLPanelEnvironmentInfo::BTN_SELECTINV("btn_select_inventory");
+const std::string LLPanelEnvironmentInfo::BTN_EDIT("btn_edit");
+const std::string LLPanelEnvironmentInfo::BTN_USEDEFAULT("btn_usedefault");
+const std::string LLPanelEnvironmentInfo::BTN_RST_ALTITUDES("btn_rst_altitudes");
+const std::string LLPanelEnvironmentInfo::SLD_DAYLENGTH("sld_day_length");
+const std::string LLPanelEnvironmentInfo::SLD_DAYOFFSET("sld_day_offset");
+const std::string LLPanelEnvironmentInfo::SLD_ALTITUDES("sld_altitudes");
+const std::string LLPanelEnvironmentInfo::ICN_GROUND("icon_ground");
+const std::string LLPanelEnvironmentInfo::ICN_WATER("icon_water");
+const std::string LLPanelEnvironmentInfo::CHK_ALLOWOVERRIDE("chk_allow_override");
+const std::string LLPanelEnvironmentInfo::LBL_TIMEOFDAY("lbl_apparent_time");
+const std::string LLPanelEnvironmentInfo::PNL_SETTINGS("pnl_environment_config");
+const std::string LLPanelEnvironmentInfo::PNL_ENVIRONMENT_ALTITUDES("pnl_environment_altitudes");
+const std::string LLPanelEnvironmentInfo::PNL_BUTTONS("pnl_environment_buttons");
+const std::string LLPanelEnvironmentInfo::PNL_DISABLED("pnl_environment_disabled");
+const std::string LLPanelEnvironmentInfo::TXT_DISABLED("txt_environment_disabled");
+const std::string LLPanelEnvironmentInfo::PNL_REGION_MSG("pnl_environment_region_msg");
+const std::string LLPanelEnvironmentInfo::SDT_DROP_TARGET("sdt_drop_target");
+
+const std::string LLPanelEnvironmentInfo::STR_LABEL_USEDEFAULT("str_label_use_default");
+const std::string LLPanelEnvironmentInfo::STR_LABEL_USEREGION("str_label_use_region");
+const std::string LLPanelEnvironmentInfo::STR_ALTITUDE_DESCRIPTION("str_altitude_desription");
+const std::string LLPanelEnvironmentInfo::STR_NO_PARCEL("str_no_parcel");
+const std::string LLPanelEnvironmentInfo::STR_CROSS_REGION("str_cross_region");
+const std::string LLPanelEnvironmentInfo::STR_LEGACY("str_legacy");
+const std::string LLPanelEnvironmentInfo::STR_DISALLOWED("str_disallowed");
+const std::string LLPanelEnvironmentInfo::STR_TOO_SMALL("str_too_small");
+
+const S32 LLPanelEnvironmentInfo::MINIMUM_PARCEL_SIZE(128);
+
+const U32 LLPanelEnvironmentInfo::DIRTY_FLAG_DAYCYCLE(0x01 << 0);
+const U32 LLPanelEnvironmentInfo::DIRTY_FLAG_DAYLENGTH(0x01 << 1);
+const U32 LLPanelEnvironmentInfo::DIRTY_FLAG_DAYOFFSET(0x01 << 2);
+const U32 LLPanelEnvironmentInfo::DIRTY_FLAG_ALTITUDES(0x01 << 3);
+
+const U32 LLPanelEnvironmentInfo::DIRTY_FLAG_MASK(
+ LLPanelEnvironmentInfo::DIRTY_FLAG_DAYCYCLE |
+ LLPanelEnvironmentInfo::DIRTY_FLAG_DAYLENGTH |
+ LLPanelEnvironmentInfo::DIRTY_FLAG_DAYOFFSET |
+ LLPanelEnvironmentInfo::DIRTY_FLAG_ALTITUDES);
+
+const U32 ALTITUDE_SLIDER_COUNT = 3;
+const F32 ALTITUDE_DEFAULT_HEIGHT_STEP = 1000;
+const U32 ALTITUDE_MARKERS_COUNT = 3;
+const U32 ALTITUDE_PREFIXERS_COUNT = 5;
+
+const std::string slider_marker_base = "mark";
+
+const std::string alt_sliders[] = {
+ "sld1",
+ "sld2",
+ "sld3",
+};
+
+const std::string alt_prefixes[] = {
+ "alt1",
+ "alt2",
+ "alt3",
+ "ground",
+ "water",
+};
+
+const std::string alt_panels[] = {
+ "pnl_alt1",
+ "pnl_alt2",
+ "pnl_alt3",
+ "pnl_ground",
+ "pnl_water",
+};
+
+static LLDefaultChildRegistry::Register<LLSettingsDropTarget> r("settings_drop_target");
+
+//=========================================================================
+LLPanelEnvironmentInfo::LLPanelEnvironmentInfo():
+ mCurrentEnvironment(),
+ mDirtyFlag(0),
+ mEditorLastParcelId(INVALID_PARCEL_ID),
+ mCrossRegion(false),
+ mNoSelection(false),
+ mNoEnvironment(false),
+ mCurEnvVersion(INVALID_PARCEL_ENVIRONMENT_VERSION),
+ mSettingsFloater(),
+ mEditFloater(),
+ mAllowOverride(true)
+{
+}
+
+LLPanelEnvironmentInfo::~LLPanelEnvironmentInfo()
+{
+ if (mChangeMonitor.connected())
+ mChangeMonitor.disconnect();
+ if (mCommitConnection.connected())
+ mCommitConnection.disconnect();
+ if (mUpdateConnection.connected())
+ mUpdateConnection.disconnect();
+}
+
+BOOL LLPanelEnvironmentInfo::postBuild()
+{
+
+ getChild<LLUICtrl>(BTN_USEDEFAULT)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnDefault(); });
+ getChild<LLUICtrl>(BTN_SELECTINV)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnSelect(); });
+ getChild<LLUICtrl>(BTN_EDIT)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnEdit(); });
+ getChild<LLUICtrl>(BTN_RST_ALTITUDES)->setCommitCallback([this](LLUICtrl *, const LLSD &){ onBtnRstAltitudes(); });
+
+ getChild<LLUICtrl>(SLD_DAYLENGTH)->setCommitCallback([this](LLUICtrl *, const LLSD &value) { onSldDayLengthChanged(value.asReal()); });
+ getChild<LLSliderCtrl>(SLD_DAYLENGTH)->setSliderMouseUpCallback([this](LLUICtrl *, const LLSD &) { onDayLenOffsetMouseUp(); });
+ getChild<LLSliderCtrl>(SLD_DAYLENGTH)->setSliderEditorCommitCallback([this](LLUICtrl *, const LLSD &) { onDayLenOffsetMouseUp(); });
+ getChild<LLUICtrl>(SLD_DAYOFFSET)->setCommitCallback([this](LLUICtrl *, const LLSD &value) { onSldDayOffsetChanged(value.asReal()); });
+ getChild<LLSliderCtrl>(SLD_DAYOFFSET)->setSliderMouseUpCallback([this](LLUICtrl *, const LLSD &) { onDayLenOffsetMouseUp(); });
+ getChild<LLSliderCtrl>(SLD_DAYOFFSET)->setSliderEditorCommitCallback([this](LLUICtrl *, const LLSD &) { onDayLenOffsetMouseUp(); });
+
+ getChild<LLMultiSliderCtrl>(SLD_ALTITUDES)->setCommitCallback([this](LLUICtrl *cntrl, const LLSD &value) { onAltSliderCallback(cntrl, value); });
+ getChild<LLMultiSliderCtrl>(SLD_ALTITUDES)->setSliderMouseUpCallback([this](LLUICtrl *, const LLSD &) { onAltSliderMouseUp(); });
+
+ mChangeMonitor = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32 version) { onEnvironmentChanged(env, version); });
+
+ for (U32 idx = 0; idx < ALTITUDE_SLIDER_COUNT; idx++)
+ {
+ LLSettingsDropTarget* drop_target = findChild<LLSettingsDropTarget>("sdt_" + alt_prefixes[idx]);
+ if (drop_target)
+ {
+ drop_target->setPanel(this, alt_sliders[idx]);
+ }
+ // set initial values to prevent [ALTITUDE] from displaying
+ updateAltLabel(alt_prefixes[idx], idx + 2, idx * 1000);
+ }
+ getChild<LLSettingsDropTarget>("sdt_" + alt_prefixes[3])->setPanel(this, alt_prefixes[3]);
+ getChild<LLSettingsDropTarget>("sdt_" + alt_prefixes[4])->setPanel(this, alt_prefixes[4]);
+
+ return TRUE;
+}
+
+// virtual
+void LLPanelEnvironmentInfo::onOpen(const LLSD& key)
+{
+ refreshFromSource();
+}
+
+// virtual
+void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility)
+ {
+ gIdleCallbacks.addFunction(onIdlePlay, this);
+ }
+ else
+ {
+ commitDayLenOffsetChanges(false); // arrow-key changes
+
+ LLFloaterSettingsPicker *picker = getSettingsPicker(false);
+ if (picker)
+ {
+ picker->closeFloater();
+ }
+
+ gIdleCallbacks.deleteFunction(onIdlePlay, this);
+ LLFloaterEditExtDayCycle *dayeditor = getEditFloater(false);
+ if (mCommitConnection.connected())
+ mCommitConnection.disconnect();
+
+ if (dayeditor)
+ {
+ if (dayeditor->isDirty())
+ dayeditor->refresh();
+ else
+ {
+ dayeditor->closeFloater();
+ mEditFloater.markDead();
+ }
+ }
+ }
+
+}
+
+void LLPanelEnvironmentInfo::refresh()
+{
+ if (gDisconnected)
+ return;
+
+ if (!setControlsEnabled(canEdit()))
+ return;
+
+ if (!mCurrentEnvironment)
+ {
+ return;
+ }
+
+ F32Hours daylength(mCurrentEnvironment->mDayLength);
+ F32Hours dayoffset(mCurrentEnvironment->mDayOffset);
+
+ if (dayoffset.value() > 12.0f)
+ dayoffset -= F32Hours(24.0);
+
+ getChild<LLSliderCtrl>(SLD_DAYLENGTH)->setValue(daylength.value());
+ getChild<LLSliderCtrl>(SLD_DAYOFFSET)->setValue(dayoffset.value());
+
+ udpateApparentTimeOfDay();
+
+ updateEditFloater(mCurrentEnvironment, canEdit());
+
+ LLEnvironment::altitude_list_t altitudes = mCurrentEnvironment->mAltitudes;
+
+ if (altitudes.size() > 0)
+ {
+ LLMultiSliderCtrl *sld = getChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ sld->clear();
+
+ for (S32 idx = 0; idx < ALTITUDE_SLIDER_COUNT; ++idx)
+ {
+ // make sure values are in range, server is supposed to validate them,
+ // but issues happen, try to fix values in such case
+ F32 altitude = llclamp(altitudes[idx + 1], sld->getMinValue(), sld->getMaxValue());
+ bool res = sld->addSlider(altitude, alt_sliders[idx]);
+ if (!res)
+ {
+ LL_WARNS_ONCE("ENVPANEL") << "Failed to validate altitude from server for parcel id" << getParcelId() << LL_ENDL;
+ // Find a spot to insert altitude.
+ // Assuming everything alright with slider, we should find new place in 11 steps top (step 25m, no overlap 100m)
+ F32 alt_step = (altitude > (sld->getMaxValue() / 2)) ? -sld->getIncrement() : sld->getIncrement();
+ for (U32 i = 0; i < 30; i++)
+ {
+ altitude += alt_step;
+ if (altitude > sld->getMaxValue())
+ {
+ altitude = sld->getMinValue();
+ }
+ else if (altitude < sld->getMinValue())
+ {
+ altitude = sld->getMaxValue();
+ }
+ res = sld->addSlider(altitude, alt_sliders[idx]);
+ if (res) break;
+ }
+ }
+ if (res)
+ {
+ // slider has some auto correction that might have kicked in
+ altitude = sld->getSliderValue(alt_sliders[idx]);
+ }
+ else
+ {
+ // Something is very very wrong
+ LL_WARNS_ONCE("ENVPANEL") << "Failed to set up altitudes for parcel id " << getParcelId() << LL_ENDL;
+ }
+ updateAltLabel(alt_prefixes[idx], idx + 2, altitude);
+ mAltitudes[alt_sliders[idx]] = AltitudeData(idx + 2, idx, altitude);
+ }
+ if (sld->getCurNumSliders() != ALTITUDE_SLIDER_COUNT)
+ {
+ LL_WARNS("ENVPANEL") << "Failed to add altitude sliders!" << LL_ENDL;
+ }
+ readjustAltLabels();
+ sld->resetCurSlider();
+ }
+
+ updateAltLabel(alt_prefixes[3], 1, 0); // ground
+ updateAltLabel(alt_prefixes[4], 0, 0); // water
+
+}
+
+void LLPanelEnvironmentInfo::refreshFromEstate()
+{
+ LLViewerRegion *pRegion = gAgent.getRegion();
+
+ bool oldAO = mAllowOverride;
+ mAllowOverride = (isRegion() && LLEstateInfoModel::instance().getAllowEnvironmentOverride()) || pRegion->getAllowEnvironmentOverride();
+ if (oldAO != mAllowOverride)
+ refresh();
+}
+
+std::string LLPanelEnvironmentInfo::getNameForTrackIndex(S32 index)
+{
+ std::string invname;
+ if (!mCurrentEnvironment || index < LLSettingsDay::TRACK_WATER || index >= LLSettingsDay::TRACK_MAX)
+ {
+ invname = getString(STRING_EMPTY_NAME);
+ }
+ else if (mCurrentEnvironment->mDayCycleName.empty())
+ {
+ invname = mCurrentEnvironment->mNameList[index];
+
+ if (invname.empty())
+ {
+ if (index <= LLSettingsDay::TRACK_GROUND_LEVEL)
+ invname = getString(isRegion() ? STRING_EMPTY_NAME : STRING_REGION_ENV);
+ }
+ }
+ else if (!mCurrentEnvironment->mDayCycle->isTrackEmpty(index))
+ {
+ invname = mCurrentEnvironment->mDayCycleName;
+ }
+
+
+ if (invname.empty())
+ {
+ invname = getNameForTrackIndex(index - 1);
+ if (invname[0] != '(')
+ invname = "(" + invname + ")";
+ }
+
+ return invname;
+}
+
+LLFloaterSettingsPicker * LLPanelEnvironmentInfo::getSettingsPicker(bool create)
+{
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mSettingsFloater.get());
+
+ // Show the dialog
+ if (!picker && create)
+ {
+ picker = new LLFloaterSettingsPicker(this,
+ LLUUID::null);
+
+ mSettingsFloater = picker->getHandle();
+
+ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitted(data["ItemId"].asUUID()); });
+ }
+
+ return picker;
+}
+
+LLFloaterEditExtDayCycle * LLPanelEnvironmentInfo::getEditFloater(bool create)
+{
+ static const S32 FOURHOURS(4 * 60 * 60);
+ LLFloaterEditExtDayCycle *editor = static_cast<LLFloaterEditExtDayCycle *>(mEditFloater.get());
+
+ // Show the dialog
+ if (!editor && create)
+ {
+ LLSD params(LLSDMap(LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT, isRegion() ? LLFloaterEditExtDayCycle::CONTEXT_REGION : LLFloaterEditExtDayCycle::CONTEXT_PARCEL)
+ (LLFloaterEditExtDayCycle::KEY_DAY_LENGTH, mCurrentEnvironment ? (S32)(mCurrentEnvironment->mDayLength.value()) : FOURHOURS));
+
+ editor = (LLFloaterEditExtDayCycle *)LLFloaterReg::getInstance(FLOATER_DAY_CYCLE_EDIT, params);
+
+ if (!editor)
+ return nullptr;
+ mEditFloater = editor->getHandle();
+ }
+
+ if (editor && !mCommitConnection.connected())
+ mCommitConnection = editor->setEditCommitSignal([this](LLSettingsDay::ptr_t pday) { onEditCommitted(pday); });
+
+ return editor;
+}
+
+
+void LLPanelEnvironmentInfo::updateEditFloater(const LLEnvironment::EnvironmentInfo::ptr_t &nextenv, bool enable)
+{
+ LLFloaterEditExtDayCycle *dayeditor(getEditFloater(false));
+
+ if (!dayeditor || !dayeditor->isInVisibleChain())
+ return;
+
+ if (!nextenv || !nextenv->mDayCycle || !enable)
+ {
+ if (mCommitConnection.connected())
+ mCommitConnection.disconnect();
+
+ if (dayeditor->isDirty())
+ dayeditor->refresh();
+ else
+ dayeditor->closeFloater();
+ }
+ else if (dayeditor->getEditingAssetId() != nextenv->mDayCycle->getAssetId()
+ || mEditorLastParcelId != nextenv->mParcelId
+ || mEditorLastRegionId != nextenv->mRegionId)
+ {
+ // Ignore dirty
+ // If parcel selection changed whatever we do except saving to inventory with
+ // old settings will be invalid.
+ mEditorLastParcelId = nextenv->mParcelId;
+ mEditorLastRegionId = nextenv->mRegionId;
+
+ dayeditor->setEditDayCycle(nextenv->mDayCycle);
+ }
+}
+
+bool LLPanelEnvironmentInfo::setControlsEnabled(bool enabled)
+{
+ bool is_unavailable(false);
+ bool is_legacy = (mCurrentEnvironment) ? mCurrentEnvironment->mIsLegacy : true;
+ bool is_bigenough = isLargeEnough();
+
+ if (mNoEnvironment || (!LLEnvironment::instance().isExtendedEnvironmentEnabled() && !isRegion()))
+ {
+ is_unavailable = true;
+ getChild<LLTextBox>(TXT_DISABLED)->setText(getString(STR_LEGACY));
+ }
+ else if (mNoSelection)
+ {
+ is_unavailable = true;
+ getChild<LLTextBox>(TXT_DISABLED)->setText(getString(STR_NO_PARCEL));
+ }
+ else if (mCrossRegion)
+ {
+ is_unavailable = true;
+ getChild<LLTextBox>(TXT_DISABLED)->setText(getString(STR_CROSS_REGION));
+ }
+ else if (!isRegion() && !mAllowOverride)
+ {
+ is_unavailable = true;
+ getChild<LLTextBox>(TXT_DISABLED)->setText(getString(STR_DISALLOWED));
+ }
+ else if (!is_bigenough)
+ {
+ is_unavailable = true;
+ getChild<LLTextBox>(TXT_DISABLED)->setText(getString(STR_TOO_SMALL));
+ }
+
+ if (is_unavailable)
+ {
+ getChild<LLUICtrl>(PNL_SETTINGS)->setVisible(false);
+ getChild<LLUICtrl>(PNL_BUTTONS)->setVisible(false);
+ getChild<LLUICtrl>(PNL_DISABLED)->setVisible(true);
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(false);
+ getChild<LLUICtrl>(PNL_REGION_MSG)->setVisible(false);
+ updateEditFloater(mCurrentEnvironment, false);
+
+ return false;
+ }
+ getChild<LLUICtrl>(PNL_SETTINGS)->setVisible(true);
+ getChild<LLUICtrl>(PNL_BUTTONS)->setVisible(true);
+ getChild<LLUICtrl>(PNL_DISABLED)->setVisible(false);
+ getChild<LLUICtrl>(PNL_REGION_MSG)->setVisible(isRegion());
+
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setVisible(LLEnvironment::instance().isExtendedEnvironmentEnabled());
+ getChild<LLUICtrl>(BTN_RST_ALTITUDES)->setVisible(isRegion());
+
+ bool can_enable = enabled && !is_legacy && mCurrentEnvironment && (mCurEnvVersion != INVALID_PARCEL_ENVIRONMENT_VERSION);
+ getChild<LLUICtrl>(BTN_SELECTINV)->setEnabled(can_enable);
+ getChild<LLUICtrl>(BTN_USEDEFAULT)->setEnabled(can_enable);
+ getChild<LLUICtrl>(BTN_EDIT)->setEnabled(can_enable);
+ getChild<LLUICtrl>(SLD_DAYLENGTH)->setEnabled(can_enable);
+ getChild<LLUICtrl>(SLD_DAYOFFSET)->setEnabled(can_enable);
+ getChild<LLUICtrl>(SLD_ALTITUDES)->setEnabled(can_enable && isRegion());
+ getChild<LLUICtrl>(ICN_GROUND)->setColor((can_enable && isRegion()) ? LLColor4::white : LLColor4::grey % 0.8f);
+ getChild<LLUICtrl>(ICN_WATER)->setColor((can_enable && isRegion()) ? LLColor4::white : LLColor4::grey % 0.8f);
+ getChild<LLUICtrl>(BTN_RST_ALTITUDES)->setEnabled(can_enable && isRegion());
+ getChild<LLUICtrl>(PNL_ENVIRONMENT_ALTITUDES)->setEnabled(can_enable);
+ getChild<LLUICtrl>(CHK_ALLOWOVERRIDE)->setEnabled(can_enable && isRegion());
+
+ for (U32 idx = 0; idx < ALTITUDE_MARKERS_COUNT; idx++)
+ {
+ LLUICtrl* marker = findChild<LLUICtrl>(slider_marker_base + llformat("%u", idx));
+ if (marker)
+ {
+ static LLColor4 marker_color(0.75f, 0.75f, 0.75f, 1.f);
+ marker->setColor((can_enable && isRegion()) ? marker_color : marker_color % 0.3f);
+ }
+ }
+
+ for (U32 idx = 0; idx < ALTITUDE_PREFIXERS_COUNT; idx++)
+ {
+ LLSettingsDropTarget* drop_target = findChild<LLSettingsDropTarget>("sdt_" + alt_prefixes[idx]);
+ if (drop_target)
+ {
+ drop_target->setDndEnabled(can_enable);
+ }
+ }
+
+ return true;
+}
+
+void LLPanelEnvironmentInfo::setDirtyFlag(U32 flag)
+{
+ mDirtyFlag |= flag;
+}
+
+void LLPanelEnvironmentInfo::clearDirtyFlag(U32 flag)
+{
+ mDirtyFlag &= ~flag;
+}
+
+void LLPanelEnvironmentInfo::updateAltLabel(const std::string &alt_prefix, U32 sky_index, F32 alt_value)
+{
+ LLMultiSliderCtrl *sld = findChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ if (!sld)
+ {
+ LL_WARNS() << "Failed to find slider " << SLD_ALTITUDES << LL_ENDL;
+ return;
+ }
+ LLRect sld_rect = sld->getRect();
+ S32 sld_range = sld_rect.getHeight();
+ S32 sld_bottom = sld_rect.mBottom;
+ S32 sld_offset = sld_rect.getWidth(); // Roughly identical to thumb's width in slider.
+ S32 pos = (sld_range - sld_offset) * ((alt_value - 100) / (4000 - 100));
+
+ // get related views
+ LLTextBox* text = findChild<LLTextBox>("txt_" + alt_prefix);
+ LLLineEditor *field = findChild<LLLineEditor>("edt_invname_" + alt_prefix);
+ LLView *alt_panel = findChild<LLView>("pnl_" + alt_prefix);
+
+ if (text && (sky_index > 1))
+ {
+ // update text
+ std::ostringstream convert;
+ convert << alt_value;
+ text->setTextArg("[ALTITUDE]", convert.str());
+ convert.str("");
+ convert.clear();
+ convert << sky_index;
+ text->setTextArg("[INDEX]", convert.str());
+ }
+
+ if (field)
+ {
+ field->setText(getNameForTrackIndex(sky_index));
+ }
+
+ if (alt_panel && (sky_index > 1))
+ {
+ // move containing panel
+ LLRect rect = alt_panel->getRect();
+ S32 height = rect.getHeight();
+ rect.mBottom = sld_bottom + (sld_offset / 2 + 1) + pos - (height / 2);
+ rect.mTop = rect.mBottom + height;
+ alt_panel->setRect(rect);
+ }
+
+}
+
+void LLPanelEnvironmentInfo::readjustAltLabels()
+{
+ // Re-adjust all labels
+ // Very simple "adjust after the fact" method
+ // Note: labels can be in any order
+
+ LLMultiSliderCtrl *sld = findChild<LLMultiSliderCtrl>(SLD_ALTITUDES);
+ if (!sld) return;
+
+ LLView* view_midle = NULL;
+ U32 midle_ind = 0;
+ S32 shift_up = 0;
+ S32 shift_down = 0;
+ LLRect sld_rect = sld->getRect();
+
+ // Find the middle one
+ for (U32 i = 0; i < ALTITUDE_SLIDER_COUNT; i++)
+ {
+ LLView* cmp_view = findChild<LLView>(alt_panels[i], true);
+ if (!cmp_view) return;
+ LLRect cmp_rect = cmp_view->getRect();
+ S32 pos = 0;
+ shift_up = 0;
+ shift_down = 0;
+
+ for (U32 j = 0; j < ALTITUDE_SLIDER_COUNT; j++)
+ {
+ if (i != j)
+ {
+ LLView* intr_view = findChild<LLView>(alt_panels[j], true);
+ if (!intr_view) return;
+ LLRect intr_rect = intr_view->getRect();
+ if (cmp_rect.mBottom >= intr_rect.mBottom)
+ {
+ pos++;
+ }
+ if (intr_rect.mBottom <= cmp_rect.mTop && intr_rect.mBottom >= cmp_rect.mBottom)
+ {
+ shift_up = cmp_rect.mTop - intr_rect.mBottom;
+ }
+ else if (intr_rect.mTop >= cmp_rect.mBottom && intr_rect.mBottom <= cmp_rect.mBottom)
+ {
+ shift_down = cmp_rect.mBottom - intr_rect.mTop;
+ }
+ }
+ }
+ if (pos == 1) // middle
+ {
+ view_midle = cmp_view;
+ midle_ind = i;
+ break;
+ }
+ }
+
+ // Account for edges
+ LLRect midle_rect = view_midle->getRect();
+ F32 factor = 0.5f;
+ S32 edge_zone_height = midle_rect.getHeight() * 1.5f;
+
+ if (midle_rect.mBottom - sld_rect.mBottom < edge_zone_height)
+ {
+ factor = 1 - ((midle_rect.mBottom - sld_rect.mBottom) / (edge_zone_height * 2));
+ }
+ else if (sld_rect.mTop - midle_rect.mTop < edge_zone_height )
+ {
+ factor = ((sld_rect.mTop - midle_rect.mTop) / (edge_zone_height * 2));
+ }
+
+ S32 shift_middle = (S32)(((F32)shift_down * factor) + ((F32)shift_up * (1.f - factor)));
+ shift_down = shift_down - shift_middle;
+ shift_up = shift_up - shift_middle;
+
+ // fix crossings
+ for (U32 i = 0; i < ALTITUDE_SLIDER_COUNT; i++)
+ {
+ if (i != midle_ind)
+ {
+ LLView* trn_view = findChild<LLView>(alt_panels[i], true);
+ LLRect trn_rect = trn_view->getRect();
+
+ if (trn_rect.mBottom <= midle_rect.mTop && trn_rect.mBottom >= midle_rect.mBottom)
+ {
+ // Approximate shift
+ trn_rect.translate(0, shift_up);
+ trn_view->setRect(trn_rect);
+ }
+ else if (trn_rect.mTop >= midle_rect.mBottom && trn_rect.mBottom <= midle_rect.mBottom)
+ {
+ // Approximate shift
+ trn_rect.translate(0, shift_down);
+ trn_view->setRect(trn_rect);
+ }
+ }
+ }
+
+ if (shift_middle != 0)
+ {
+ midle_rect.translate(0, -shift_middle); //reversed relative to others
+ view_midle->setRect(midle_rect);
+ }
+}
+
+void LLPanelEnvironmentInfo::onSldDayLengthChanged(F32 value)
+{
+ if (mCurrentEnvironment)
+ {
+ F32Hours daylength(value);
+
+ mCurrentEnvironment->mDayLength = daylength;
+ setDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+
+ udpateApparentTimeOfDay();
+ }
+}
+
+void LLPanelEnvironmentInfo::onSldDayOffsetChanged(F32 value)
+{
+ if (mCurrentEnvironment)
+ {
+ F32Hours dayoffset(value);
+
+ if (dayoffset.value() <= 0.0f)
+ dayoffset += F32Hours(24.0);
+
+ mCurrentEnvironment->mDayOffset = dayoffset;
+ setDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ udpateApparentTimeOfDay();
+ }
+}
+
+void LLPanelEnvironmentInfo::onDayLenOffsetMouseUp()
+{
+ commitDayLenOffsetChanges(true);
+}
+
+void LLPanelEnvironmentInfo::commitDayLenOffsetChanges(bool need_callback)
+{
+ if (mCurrentEnvironment && (getDirtyFlag() & (DIRTY_FLAG_DAYLENGTH | DIRTY_FLAG_DAYOFFSET)))
+ {
+ clearDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+ clearDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+
+ LLHandle<LLPanel> that_h = getHandle();
+
+ if (need_callback)
+ {
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ LLSettingsDay::ptr_t(),
+ mCurrentEnvironment->mDayLength.value(),
+ mCurrentEnvironment->mDayOffset.value(),
+ LLEnvironment::altitudes_vect_t(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+ else
+ {
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ LLSettingsDay::ptr_t(),
+ mCurrentEnvironment->mDayLength.value(),
+ mCurrentEnvironment->mDayOffset.value(),
+ LLEnvironment::altitudes_vect_t());
+ }
+
+ }
+}
+
+void LLPanelEnvironmentInfo::onAltSliderCallback(LLUICtrl *cntrl, const LLSD &data)
+{
+ LLMultiSliderCtrl *sld = (LLMultiSliderCtrl *)cntrl;
+ std::string sld_name = sld->getCurSlider();
+
+ if (sld_name.empty()) return;
+
+ F32 sld_value = sld->getCurSliderValue();
+
+ mAltitudes[sld_name].mAltitude = sld_value;
+
+ // update all labels since we could have jumped multiple and we will need to readjust
+ // (or sort by altitude, too little elements, so I didn't bother with efficiency)
+ altitudes_data_t::iterator end = mAltitudes.end();
+ altitudes_data_t::iterator iter = mAltitudes.begin();
+ altitudes_data_t::iterator iter2;
+ U32 new_index;
+ while (iter != end)
+ {
+ iter2 = mAltitudes.begin();
+ new_index = 2;
+ while (iter2 != end)
+ {
+ if (iter->second.mAltitude > iter2->second.mAltitude)
+ {
+ new_index++;
+ }
+ iter2++;
+ }
+ iter->second.mTrackIndex = new_index;
+
+ updateAltLabel(alt_prefixes[iter->second.mLabelIndex], iter->second.mTrackIndex, iter->second.mAltitude);
+ iter++;
+ }
+
+ readjustAltLabels();
+ setDirtyFlag(DIRTY_FLAG_ALTITUDES);
+}
+
+void LLPanelEnvironmentInfo::onAltSliderMouseUp()
+{
+ if (isRegion() && (getDirtyFlag() & DIRTY_FLAG_ALTITUDES))
+ {
+ clearDirtyFlag(DIRTY_FLAG_ALTITUDES);
+ clearDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+ clearDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ LLHandle<LLPanel> that_h = getHandle();
+ LLEnvironment::altitudes_vect_t alts;
+
+ for (auto alt : mAltitudes)
+ {
+ alts.push_back(alt.second.mAltitude);
+ }
+ setControlsEnabled(false);
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ LLSettingsDay::ptr_t(),
+ mCurrentEnvironment ? mCurrentEnvironment->mDayLength.value() : -1,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayOffset.value() : -1,
+ alts);
+ }
+}
+
+void LLPanelEnvironmentInfo::onBtnDefault()
+{
+ LLHandle<LLPanel> that_h = getHandle();
+ S32 parcel_id = getParcelId();
+ LLNotificationsUtil::add("SettingsConfirmReset", LLSD(), LLSD(),
+ [that_h, parcel_id](const LLSD&notif, const LLSD&resp)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+ if (opt == 0)
+ {
+ LLEnvironment::instance().resetParcel(parcel_id,
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+ });
+}
+
+void LLPanelEnvironmentInfo::onBtnEdit()
+{
+ static const S32 FOURHOURS(4 * 60 * 60);
+
+ LLFloaterEditExtDayCycle *dayeditor = getEditFloater();
+
+ LLSD params(LLSDMap(LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT, isRegion() ? LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION : LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL)
+ (LLFloaterEditExtDayCycle::KEY_DAY_LENGTH, mCurrentEnvironment ? (S32)(mCurrentEnvironment->mDayLength.value()) : FOURHOURS)
+ (LLFloaterEditExtDayCycle::KEY_CANMOD, LLSD::Boolean(true)));
+
+ dayeditor->openFloater(params);
+ if (mCurrentEnvironment && mCurrentEnvironment->mDayCycle)
+ {
+ dayeditor->setEditDayCycle(mCurrentEnvironment->mDayCycle);
+ if (!ends_with(mCurrentEnvironment->mDayCycle->getName(), "(customized)"))
+ {
+ dayeditor->setEditName(mCurrentEnvironment->mDayCycle->getName() + "(customized)");
+ }
+ }
+ else
+ dayeditor->setEditDefaultDayCycle();
+}
+
+void LLPanelEnvironmentInfo::onBtnSelect()
+{
+ LLFloaterSettingsPicker *picker = getSettingsPicker();
+ if (picker)
+ {
+ LLUUID item_id;
+ if (mCurrentEnvironment && mCurrentEnvironment->mDayCycle)
+ {
+ item_id = LLFloaterSettingsPicker::findItemID(mCurrentEnvironment->mDayCycle->getAssetId(), false, false);
+ }
+ picker->setSettingsFilter(LLSettingsType::ST_NONE);
+ picker->setSettingsItemId(item_id);
+ picker->openFloater();
+ picker->setFocus(TRUE);
+ }
+}
+
+void LLPanelEnvironmentInfo::onBtnRstAltitudes()
+{
+ if (isRegion())
+ {
+ LLHandle<LLPanel> that_h = getHandle();
+ LLEnvironment::altitudes_vect_t alts;
+
+ clearDirtyFlag(DIRTY_FLAG_ALTITUDES);
+ clearDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+ clearDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ for (S32 idx = 1; idx <= ALTITUDE_SLIDER_COUNT; ++idx)
+ {
+ F32 new_height = idx * ALTITUDE_DEFAULT_HEIGHT_STEP;
+ alts.push_back(new_height);
+ }
+
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ LLSettingsDay::ptr_t(),
+ mCurrentEnvironment ? mCurrentEnvironment->mDayLength.value() : -1,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayOffset.value() : -1,
+ alts,
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+}
+
+void LLPanelEnvironmentInfo::udpateApparentTimeOfDay()
+{
+ static const F32 SECONDSINDAY(24.0 * 60.0 * 60.0);
+
+ if ((!mCurrentEnvironment) || (mCurrentEnvironment->mDayLength.value() < 1.0) || (mCurrentEnvironment->mDayOffset.value() < 1.0))
+ {
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setVisible(false);
+ return;
+ }
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setVisible(true);
+
+ S32Seconds now(LLDate::now().secondsSinceEpoch());
+
+ now += mCurrentEnvironment->mDayOffset;
+
+ F32 perc = (F32)(now.value() % mCurrentEnvironment->mDayLength.value()) / (F32)(mCurrentEnvironment->mDayLength.value());
+
+ S32Seconds secondofday((S32)(perc * SECONDSINDAY));
+ S32Hours hourofday(secondofday);
+ S32Seconds secondofhour(secondofday - hourofday);
+ S32Minutes minutesofhour(secondofhour);
+ bool am_pm(hourofday.value() >= 12);
+
+ if (hourofday.value() < 1)
+ hourofday = S32Hours(12);
+ if (hourofday.value() > 12)
+ hourofday -= S32Hours(12);
+
+ std::string lblminute(((minutesofhour.value() < 10) ? "0" : "") + LLSD(minutesofhour.value()).asString());
+
+
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setTextArg("[HH]", LLSD(hourofday.value()).asString());
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setTextArg("[MM]", lblminute);
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setTextArg("[AP]", std::string(am_pm ? "PM" : "AM"));
+ getChild<LLUICtrl>(LBL_TIMEOFDAY)->setTextArg("[PRC]", LLSD((S32)(100 * perc)).asString());
+
+}
+
+void LLPanelEnvironmentInfo::onIdlePlay(void *data)
+{
+ ((LLPanelEnvironmentInfo *)data)->udpateApparentTimeOfDay();
+}
+
+
+void LLPanelEnvironmentInfo::onPickerCommitted(LLUUID item_id, std::string source)
+{
+ if (source == alt_prefixes[4])
+ {
+ onPickerCommitted(item_id, 0);
+ }
+ else if (source == alt_prefixes[3])
+ {
+ onPickerCommitted(item_id, 1);
+ }
+ else
+ {
+ onPickerCommitted(item_id, mAltitudes[source].mTrackIndex);
+ }
+}
+
+void LLPanelEnvironmentInfo::onPickerCommitted(LLUUID item_id, S32 track_num)
+{
+ LLInventoryItem *itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLHandle<LLPanel> that_h = getHandle();
+ clearDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+ clearDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ U32 flags(0);
+
+ if (itemp)
+ {
+ if (!itemp->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOMOD;
+ if (!itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ flags |= LLSettingsBase::FLAG_NOTRANS;
+ }
+
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ itemp->getAssetUUID(),
+ itemp->getName(),
+ track_num,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayLength.value() : -1,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayOffset.value() : -1,
+ flags,
+ LLEnvironment::altitudes_vect_t(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+}
+
+void LLPanelEnvironmentInfo::onEditCommitted(LLSettingsDay::ptr_t newday)
+{
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ LLEnvironment::instance().updateEnvironment();
+ if (!newday)
+ {
+ LL_WARNS("ENVPANEL") << "Editor committed an empty day. Do nothing." << LL_ENDL;
+ return;
+ }
+ if (!mCurrentEnvironment)
+ {
+ // Attempting to save mid update?
+ LL_WARNS("ENVPANEL") << "Failed to apply changes from editor! Dirty state: " << mDirtyFlag << " env version: " << mCurEnvVersion << LL_ENDL;
+ return;
+ }
+ size_t newhash(newday->getHash());
+ size_t oldhash((mCurrentEnvironment->mDayCycle) ? mCurrentEnvironment->mDayCycle->getHash() : 0);
+
+ if (newhash != oldhash)
+ {
+ LLHandle<LLPanel> that_h = getHandle();
+ clearDirtyFlag(DIRTY_FLAG_DAYLENGTH);
+ clearDirtyFlag(DIRTY_FLAG_DAYOFFSET);
+
+ LLEnvironment::instance().updateParcel(getParcelId(),
+ newday,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayLength.value() : -1,
+ mCurrentEnvironment ? mCurrentEnvironment->mDayOffset.value() : -1,
+ LLEnvironment::altitudes_vect_t(),
+ [that_h](S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo) { _onEnvironmentReceived(that_h, parcel_id, envifo); });
+ }
+}
+
+void LLPanelEnvironmentInfo::onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 new_version)
+{
+ if (new_version < INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // cleanups and local changes, we are only interested in changes sent by server
+ return;
+ }
+
+ LL_DEBUGS("ENVPANEL") << "Received environment update " << mCurEnvVersion << " " << new_version << LL_ENDL;
+
+ // Environment comes from different sources, from environment update callbacks,
+ // from hovers (causes callbacks on version change) and from personal requests
+ // filter out duplicates and out of order packets by checking parcel environment version.
+
+ if (isRegion())
+ {
+ // Note: region uses same init versions as parcel
+ if (env == LLEnvironment::ENV_REGION
+ // version should be always growing, UNSET_PARCEL_ENVIRONMENT_VERSION is backup case
+ && (mCurEnvVersion < new_version || mCurEnvVersion <= UNSET_PARCEL_ENVIRONMENT_VERSION))
+ {
+ if (new_version >= UNSET_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any
+ mCurEnvVersion = new_version;
+ }
+ mCurrentEnvironment.reset();
+ refreshFromSource();
+ }
+ }
+ else if ((env == LLEnvironment::ENV_PARCEL)
+ && (getParcelId() == LLViewerParcelMgr::instance().getAgentParcelId()))
+ {
+ LLParcel *parcel = getParcel();
+ if (parcel)
+ {
+ // first for parcel own settings, second is for case when parcel uses region settings
+ if (mCurEnvVersion < new_version
+ || (mCurEnvVersion != new_version && new_version == UNSET_PARCEL_ENVIRONMENT_VERSION))
+ {
+ // 'pending state' to prevent re-request on following onEnvironmentChanged if there will be any
+ mCurEnvVersion = new_version;
+ mCurrentEnvironment.reset();
+
+ refreshFromSource();
+ }
+ else if (mCurrentEnvironment)
+ {
+ // update controls
+ refresh();
+ }
+ }
+ }
+}
+
+
+void LLPanelEnvironmentInfo::onPickerAssetDownloaded(LLSettingsBase::ptr_t settings)
+{
+ LLSettingsVODay::buildFromOtherSetting(settings, [this](LLSettingsDay::ptr_t pday)
+ {
+ if (pday)
+ {
+ mCurrentEnvironment->mDayCycle = pday;
+ setDirtyFlag(DIRTY_FLAG_DAYCYCLE);
+ }
+ refresh();
+ });
+}
+
+void LLPanelEnvironmentInfo::onEnvironmentReceived(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)
+{
+ if (parcel_id != getParcelId())
+ {
+ LL_WARNS("ENVPANEL") << "Have environment for parcel " << parcel_id << " expecting " << getParcelId() << ". Discarding." << LL_ENDL;
+ return;
+ }
+ mCurrentEnvironment = envifo;
+ clearDirtyFlag(DIRTY_FLAG_MASK);
+ if (mCurrentEnvironment->mEnvVersion > INVALID_PARCEL_ENVIRONMENT_VERSION)
+ {
+ // Server provided version, use it
+ mCurEnvVersion = mCurrentEnvironment->mEnvVersion;
+ LL_DEBUGS("ENVPANEL") << " Setting environment version: " << mCurEnvVersion << " for parcel id: " << parcel_id << LL_ENDL;
+ }
+ // Backup: Version was not provided for some reason
+ else
+ {
+ LL_WARNS("ENVPANEL") << " Environment version was not provided for " << parcel_id << ", old env version: " << mCurEnvVersion << LL_ENDL;
+ }
+
+ refreshFromEstate();
+ refresh();
+
+ // todo: we have envifo and parcel env version, should we just setEnvironment() and parcel's property to prevent dupplicate requests?
+}
+
+void LLPanelEnvironmentInfo::_onEnvironmentReceived(LLHandle<LLPanel> that_h, S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo)
+{
+ LLPanelEnvironmentInfo *that = (LLPanelEnvironmentInfo *)that_h.get();
+ if (!that)
+ return;
+ that->onEnvironmentReceived(parcel_id, envifo);
+}
+
+LLSettingsDropTarget::LLSettingsDropTarget(const LLSettingsDropTarget::Params& p)
+ : LLView(p), mEnvironmentInfoPanel(NULL), mDndEnabled(false)
+{}
+
+BOOL LLSettingsDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = FALSE;
+
+ if (getParent() && mDndEnabled)
+ {
+ handled = TRUE;
+
+ switch (cargo_type)
+ {
+ case DAD_SETTINGS:
+ {
+ LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
+ if (inv_item && mEnvironmentInfoPanel)
+ {
+ LLUUID item_id = inv_item->getUUID();
+ if (gInventory.getItem(item_id))
+ {
+ *accept = ACCEPT_YES_COPY_SINGLE;
+ if (drop)
+ {
+ // might be better to use name of the element
+ mEnvironmentInfoPanel->onPickerCommitted(item_id, mTrack);
+ }
+ }
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ break;
+ }
+ default:
+ *accept = ACCEPT_NO;
+ break;
+ }
+ }
+ return handled;
+}
diff --git a/indra/newview/llpanelenvironment.h b/indra/newview/llpanelenvironment.h
new file mode 100644
index 0000000000..38e3f09e34
--- /dev/null
+++ b/indra/newview/llpanelenvironment.h
@@ -0,0 +1,222 @@
+/**
+ * @file llpanelenvironment.h
+ * @brief LLPanelExperiences class definition
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLPANELENVIRONMENT_H
+#define LL_LLPANELENVIRONMENT_H
+
+#include "llaccordionctrltab.h"
+#include "llradiogroup.h"
+#include "llcheckboxctrl.h"
+#include "llsliderctrl.h"
+#include "llsettingsdaycycle.h"
+#include "llenvironment.h"
+#include "llparcel.h"
+#include "llsettingspicker.h"
+#include "llfloatereditextdaycycle.h"
+#include "llestateinfomodel.h"
+
+class LLViewerRegion;
+
+class LLPanelEnvironmentInfo : public LLPanel
+{
+ friend class LLSettingsDropTarget;
+public:
+ LLPanelEnvironmentInfo();
+ virtual ~LLPanelEnvironmentInfo();
+
+ virtual BOOL postBuild() override;
+ virtual void onOpen(const LLSD& key) override;
+
+ virtual BOOL isDirty() const override { return getIsDirty(); }
+ virtual void onVisibilityChange(BOOL new_visibility) override;
+
+ virtual void refresh() override;
+
+ virtual bool isRegion() const = 0;
+ virtual LLParcel * getParcel() = 0;
+ virtual bool canEdit() = 0;
+ virtual S32 getParcelId() = 0;
+
+protected:
+ LOG_CLASS(LLPanelEnvironmentInfo);
+
+ static const std::string BTN_SELECTINV;
+ static const std::string BTN_EDIT;
+ static const std::string BTN_USEDEFAULT;
+ static const std::string BTN_RST_ALTITUDES;
+ static const std::string SLD_DAYLENGTH;
+ static const std::string SLD_DAYOFFSET;
+ static const std::string SLD_ALTITUDES;
+ static const std::string ICN_GROUND;
+ static const std::string ICN_WATER;
+ static const std::string CHK_ALLOWOVERRIDE;
+ static const std::string BTN_APPLY;
+ static const std::string BTN_CANCEL;
+ static const std::string LBL_TIMEOFDAY;
+ static const std::string PNL_SETTINGS;
+ static const std::string PNL_ENVIRONMENT_ALTITUDES;
+ static const std::string PNL_BUTTONS;
+ static const std::string PNL_DISABLED;
+ static const std::string PNL_REGION_MSG;
+ static const std::string TXT_DISABLED;
+ static const std::string SDT_DROP_TARGET;
+
+ static const std::string STR_LABEL_USEDEFAULT;
+ static const std::string STR_LABEL_USEREGION;
+ static const std::string STR_ALTITUDE_DESCRIPTION;
+ static const std::string STR_NO_PARCEL;
+ static const std::string STR_CROSS_REGION;
+ static const std::string STR_LEGACY;
+ static const std::string STR_DISALLOWED;
+ static const std::string STR_TOO_SMALL;
+
+ static const S32 MINIMUM_PARCEL_SIZE;
+
+ static const U32 DIRTY_FLAG_DAYCYCLE;
+ static const U32 DIRTY_FLAG_DAYLENGTH;
+ static const U32 DIRTY_FLAG_DAYOFFSET;
+ static const U32 DIRTY_FLAG_ALTITUDES;
+
+ static const U32 DIRTY_FLAG_MASK;
+
+ bool setControlsEnabled(bool enabled);
+ void setDirtyFlag(U32 flag);
+ void clearDirtyFlag(U32 flag);
+ bool getIsDirty() const { return (mDirtyFlag != 0); }
+ bool getIsDirtyFlag(U32 flag) const { return ((mDirtyFlag & flag) != 0); }
+ U32 getDirtyFlag() const { return mDirtyFlag; }
+ void updateAltLabel(const std::string &alt_prefix, U32 sky_index, F32 alt_value);
+ void readjustAltLabels();
+
+ void onSldDayLengthChanged(F32 value);
+ void onSldDayOffsetChanged(F32 value);
+ void onAltSliderCallback(LLUICtrl *cntrl, const LLSD &data);
+ void onAltSliderMouseUp();
+
+ void onBtnEdit();
+ void onBtnSelect();
+ void onBtnDefault();
+ void onBtnRstAltitudes();
+
+ void udpateApparentTimeOfDay();
+
+ void onPickerCommitted(LLUUID item_id, std::string source);
+ void onPickerCommitted(LLUUID item_id, S32 track_num = LLEnvironment::NO_TRACK);
+ void onEditCommitted(LLSettingsDay::ptr_t newday);
+ void onDayLenOffsetMouseUp();
+ void commitDayLenOffsetChanges(bool need_callback);
+
+ void onPickerAssetDownloaded(LLSettingsBase::ptr_t settings);
+ void onEnvironmentReceived(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo);
+ static void _onEnvironmentReceived(LLHandle<LLPanel> that_h, S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envifo);
+
+ virtual bool isLargeEnough() = 0;
+ virtual void refreshFromSource() = 0;
+
+ std::string getNameForTrackIndex(S32 index);
+
+ LLFloaterSettingsPicker * getSettingsPicker(bool create = true);
+ LLFloaterEditExtDayCycle * getEditFloater(bool create = true);
+ void updateEditFloater(const LLEnvironment::EnvironmentInfo::ptr_t &nextenv, bool enable);
+
+ void setCrossRegion(bool val) { mCrossRegion = val; }
+ void setNoSelection(bool val) { mNoSelection = val; }
+ void setNoEnvironmentSupport(bool val) { mNoEnvironment = val; }
+
+ LLEnvironment::EnvironmentInfo::ptr_t mCurrentEnvironment;
+
+ void onEnvironmentChanged(LLEnvironment::EnvSelection_t env, S32 version);
+
+ class AltitudeData
+ {
+ public:
+ AltitudeData() :
+ mTrackIndex(0), mLabelIndex(0), mAltitude(0)
+ {}
+ AltitudeData(U32 track_index, U32 label_index, F32 altitude) :
+ mTrackIndex(track_index), mLabelIndex(label_index), mAltitude(altitude)
+ {}
+
+ U32 mTrackIndex;
+ U32 mLabelIndex;
+ F32 mAltitude;
+ };
+ typedef std::map<std::string, AltitudeData> altitudes_data_t;
+ altitudes_data_t mAltitudes;
+ S32 mCurEnvVersion; // used to filter duplicate callbacks/refreshes
+
+protected:
+ typedef boost::signals2::connection connection_t;
+
+ void refreshFromEstate();
+ bool mAllowOverride;
+
+private:
+ static void onIdlePlay(void *);
+
+ connection_t mCommitConnection;
+ connection_t mChangeMonitor;
+ connection_t mUpdateConnection;
+
+ LLHandle<LLFloater> mSettingsFloater;
+ LLHandle<LLFloater> mEditFloater;
+ S32 mDirtyFlag;
+ S32 mEditorLastParcelId;
+ LLUUID mEditorLastRegionId;
+ bool mCrossRegion;
+ bool mNoSelection;
+ bool mNoEnvironment;
+
+};
+
+class LLSettingsDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+ LLSettingsDropTarget(const Params&);
+ ~LLSettingsDropTarget() {};
+
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ void setPanel(LLPanelEnvironmentInfo* panel, std::string track) { mEnvironmentInfoPanel = panel; mTrack = track; };
+ void setDndEnabled(bool dnd_enabled) { mDndEnabled = dnd_enabled; };
+
+protected:
+ LLPanelEnvironmentInfo* mEnvironmentInfoPanel;
+ std::string mTrack;
+ bool mDndEnabled;
+};
+#endif // LL_LLPANELENVIRONMENT_H
diff --git a/indra/newview/llpanelexperiences.cpp b/indra/newview/llpanelexperiences.cpp
index 37981b36a9..91d3b523fb 100644
--- a/indra/newview/llpanelexperiences.cpp
+++ b/indra/newview/llpanelexperiences.cpp
@@ -93,9 +93,20 @@ void LLPanelExperiences::setExperienceList( const LLSD& experiences )
item->init(public_key);
mExperiencesList->addItem(item, public_key);
+
+ const LLSD& experience_details = LLExperienceCache::instance().get(public_key);
+ if (experience_details.isUndefined())
+ {
+ LLExperienceCache::instance().get(public_key, boost::bind(&LLPanelExperiences::sortExperiencesList, this));
+ }
}
- mExperiencesList->sort();
+ sortExperiencesList();
+}
+
+void LLPanelExperiences::sortExperiencesList()
+{
+ mExperiencesList->sort();
}
void LLPanelExperiences::getExperienceIdsList(std::vector<LLUUID>& result)
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index f29fdfdecb..9d5afd1a6a 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -60,6 +60,8 @@ public:
void setExperienceList(const LLSD& experiences);
void getExperienceIdsList(std::vector<LLUUID>& result);
+ void sortExperiencesList();
+
LLExperienceItem* getSelectedExperienceItem();
void removeExperiences( const LLSD& ids );
void removeExperience( const LLUUID& id);
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 5742b5ad1a..23394b26f2 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1027,21 +1027,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
- bool allAttachments = true;
- for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
- iter != LLSelectMgr::getInstance()->getSelection()->end();iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object->isAttachment())
- {
- allAttachments = false;
- break;
- }
- }
-
- texture_ctrl->setBakeTextureEnabled(allAttachments);
-
+ texture_ctrl->setBakeTextureEnabled(TRUE);
}
else if (id.isNull())
{
@@ -1066,21 +1052,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
-
- bool allAttachments = true;
- for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
- iter != LLSelectMgr::getInstance()->getSelection()->end();iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object->isAttachment())
- {
- allAttachments = false;
- break;
- }
- }
-
- texture_ctrl->setBakeTextureEnabled(allAttachments);
+
+ texture_ctrl->setBakeTextureEnabled(TRUE);
}
}
@@ -1109,6 +1082,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bool enabled = (editable && isIdenticalPlanarTexgen());
childSetValue("checkbox planar align", align_planar && enabled);
+ childSetVisible("checkbox planar align", enabled);
childSetEnabled("checkbox planar align", enabled);
childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index e41211ddbd..ab255d5215 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -128,10 +128,6 @@ void LLPanelGroup::onOpen(const LLSD& key)
{
onBackBtnClick();
}
- else if(str_action == "create")
- {
- setGroupID(LLUUID::null);
- }
else if(str_action == "refresh_notices")
{
LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
@@ -162,12 +158,8 @@ BOOL LLPanelGroup::postBuild()
button = getChild<LLButton>("btn_refresh");
button->setClickedCallback(onBtnRefresh, this);
- getChild<LLButton>("btn_create")->setVisible(false);
-
childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL);
- childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL);
-
LLPanelGroupTab* panel_general = findChild<LLPanelGroupTab>("group_general_tab_panel");
LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("group_roles_tab_panel");
LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
@@ -223,7 +215,6 @@ void LLPanelGroup::reposButtons()
}
reposButton("btn_apply");
- reposButton("btn_create");
reposButton("btn_refresh");
reposButton("btn_cancel");
reposButton("btn_chat");
@@ -246,23 +237,6 @@ void LLPanelGroup::onBackBtnClick()
}
}
-
-void LLPanelGroup::onBtnCreate()
-{
- LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel");
- if(!panel_general)
- return;
- std::string apply_mesg;
- if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
- return;
- if ( !apply_mesg.empty() )
- {
- LLSD args;
- args["MESSAGE"] = apply_mesg;
- LLNotificationsUtil::add("GenericAlert", args);
- }
-}
-
void LLPanelGroup::onBtnRefresh(void* user_data)
{
LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
@@ -378,7 +352,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
LLButton* button_apply = findChild<LLButton>("btn_apply");
LLButton* button_refresh = findChild<LLButton>("btn_refresh");
- LLButton* button_create = findChild<LLButton>("btn_create");
LLButton* button_cancel = findChild<LLButton>("btn_cancel");
LLButton* button_call = findChild<LLButton>("btn_call");
@@ -391,8 +364,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
if(button_refresh)
button_refresh->setVisible(!is_null_group_id);
- if(button_create)
- button_create->setVisible(is_null_group_id);
if(button_cancel)
button_cancel->setVisible(!is_null_group_id);
@@ -611,18 +582,6 @@ void LLPanelGroup::showNotice(const std::string& subject,
panel_notices->showNotice(subject,message,has_inventory,inventory_name,inventory_offer);
}
-
-
-
-//static
-void LLPanelGroup::refreshCreatedGroup(const LLUUID& group_id)
-{
- LLPanelGroup* panel = LLFloaterSidePanelContainer::getPanel<LLPanelGroup>("people", "panel_group_info_sidetray");
- if(!panel)
- return;
- panel->setGroupID(group_id);
-}
-
//static
void LLPanelGroup::showNotice(const std::string& subject,
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 0b40c8b5d3..be40b08a6d 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -79,8 +79,6 @@ public:
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- static void refreshCreatedGroup(const LLUUID& group_id);
-
static void showNotice(const std::string& subject,
const std::string& message,
const LLUUID& group_id,
@@ -92,7 +90,6 @@ public:
protected:
virtual void update(LLGroupChange gc);
- void onBtnCreate();
void onBackBtnClick();
void onBtnJoin();
diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp
new file mode 100644
index 0000000000..052212dc27
--- /dev/null
+++ b/indra/newview/llpanelgroupcreate.cpp
@@ -0,0 +1,237 @@
+/**
+ * @file llpanelgroupcreate.cpp
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelgroupcreate.h"
+
+// UI includes
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llsidetraypanelcontainer.h"
+#include "llscrolllistctrl.h"
+#include "llspinctrl.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lluictrlfactory.h"
+
+// Viewer includes
+#include "llagentbenefits.h"
+#include "llfloaterreg.h"
+#include "llfloater.h"
+#include "llgroupmgr.h"
+#include "lltrans.h"
+#include "llnotificationsutil.h"
+#include "lluicolortable.h"
+
+
+const S32 MATURE_CONTENT = 1;
+const S32 NON_MATURE_CONTENT = 2;
+const S32 DECLINE_TO_STATE = 0;
+
+static LLPanelInjector<LLPanelGroupCreate> t_panel_group_creation("panel_group_creation_sidetray");
+
+LLPanelGroupCreate::LLPanelGroupCreate()
+: LLPanel()
+{
+}
+
+LLPanelGroupCreate::~LLPanelGroupCreate()
+{
+}
+
+BOOL LLPanelGroupCreate::postBuild()
+{
+ childSetCommitCallback("back", boost::bind(&LLPanelGroupCreate::onBackBtnClick, this), NULL);
+
+ mComboMature = getChild<LLComboBox>("group_mature_check", TRUE);
+ mCtrlOpenEnrollment = getChild<LLCheckBoxCtrl>("open_enrollement", TRUE);
+ mCtrlEnrollmentFee = getChild<LLCheckBoxCtrl>("check_enrollment_fee", TRUE);
+ mEditCharter = getChild<LLTextEditor>("charter", TRUE);
+ mSpinEnrollmentFee = getChild<LLSpinCtrl>("spin_enrollment_fee", TRUE);
+ mMembershipList = getChild<LLScrollListCtrl>("membership_list", TRUE);
+
+ mCreateButton = getChild<LLButton>("btn_create", TRUE);
+ mCreateButton->setCommitCallback(boost::bind(&LLPanelGroupCreate::onBtnCreate, this));
+
+ mGroupNameEditor = getChild<LLLineEditor>("group_name_editor", TRUE);
+ mGroupNameEditor->setPrevalidate(LLTextValidate::validateASCIINoLeadingSpace);
+
+ mInsignia = getChild<LLTextureCtrl>("insignia", TRUE);
+ mInsignia->setAllowLocalTexture(FALSE);
+ mInsignia->setCanApplyImmediately(FALSE);
+
+ return TRUE;
+}
+
+void LLPanelGroupCreate::onOpen(const LLSD& key)
+{
+ mInsignia->setImageAssetID(LLUUID::null);
+ mInsignia->setImageAssetName(mInsignia->getDefaultImageName());
+ mGroupNameEditor->clear();
+ mEditCharter->clear();
+ mSpinEnrollmentFee->set(0.f);
+ mCtrlEnrollmentFee->set(FALSE);
+ mCtrlOpenEnrollment->set(FALSE);
+ mMembershipList->clearRows();
+
+ // populate list
+ addMembershipRow("Base");
+ addMembershipRow("Premium");
+ addMembershipRow("Premium Plus");
+ addMembershipRow("Internal");// Present only if you are already in one, needed for testing
+
+ S32 cost = LLAgentBenefitsMgr::current().getCreateGroupCost();
+ mCreateButton->setLabelArg("[COST]", llformat("%d", cost));
+}
+
+//static
+void LLPanelGroupCreate::refreshCreatedGroup(const LLUUID& group_id)
+{
+ LLSD params;
+ params["group_id"] = group_id;
+ params["open_tab_name"] = "panel_group_info_sidetray";
+ LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params);
+}
+
+void LLPanelGroupCreate::addMembershipRow(const std::string &name)
+{
+ if (LLAgentBenefitsMgr::has(name))
+ {
+ bool is_current = LLAgentBenefitsMgr::isCurrent(name);
+
+ LLScrollListItem::Params item_params;
+ LLScrollListCell::Params cell_params;
+ cell_params.font = LLFontGL::getFontSansSerif();
+ // Start out right justifying numeric displays
+ cell_params.font_halign = LLFontGL::LEFT;
+ if (is_current)
+ {
+ cell_params.color = LLUIColorTable::instance().getColor("DrYellow");
+ }
+
+ cell_params.column = "clmn_name";
+ std::string mem_str = name + "Membership";
+ if (is_current)
+ {
+ cell_params.value = LLTrans::getString(mem_str) + " " + getString("current_membership");
+ }
+ else
+ {
+ cell_params.value = LLTrans::getString(mem_str);
+ }
+ item_params.columns.add(cell_params);
+ cell_params.column = "clmn_price";
+ cell_params.value = llformat("L$ %d",LLAgentBenefitsMgr::get(name).getCreateGroupCost());
+ item_params.columns.add(cell_params);
+ mMembershipList->addRow(item_params);
+ }
+}
+
+void LLPanelGroupCreate::onBackBtnClick()
+{
+ LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+ if(parent)
+ {
+ parent->openPreviousPanel();
+ }
+}
+
+bool LLPanelGroupCreate::confirmMatureApply(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // 0 == Yes
+ // 1 == No
+ // 2 == Cancel
+ switch (option)
+ {
+ case 0:
+ mComboMature->setCurrentByIndex(MATURE_CONTENT);
+ createGroup();
+ break;
+ case 1:
+ mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
+ createGroup();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void LLPanelGroupCreate::onBtnCreate()
+{
+ LL_INFOS() << "Validating group creation" << LL_ENDL;
+
+ // Validate the group name length.
+ std::string gr_name = mGroupNameEditor->getText();
+ LLStringUtil::trim(gr_name);
+ S32 group_name_len = gr_name.size();
+ if (group_name_len < DB_GROUP_NAME_MIN_LEN
+ || group_name_len > DB_GROUP_NAME_STR_LEN)
+ {
+ LLSD args;
+ args["MIN_LEN"] = DB_GROUP_NAME_MIN_LEN;
+ args["MAX_LEN"] = DB_GROUP_NAME_STR_LEN;
+ LLNotificationsUtil::add("GroupNameLengthWarning", args);
+ }
+ else
+ // Check to make sure mature has been set
+ if (mComboMature &&
+ mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
+ {
+ LLNotificationsUtil::add("SetGroupMature", LLSD(), LLSD(),
+ boost::bind(&LLPanelGroupCreate::confirmMatureApply, this, _1, _2));
+ }
+ else
+ {
+ createGroup();
+ }
+}
+
+void LLPanelGroupCreate::createGroup()
+{
+ LL_INFOS() << "Creating group" << LL_ENDL;
+
+ U32 enrollment_fee = (mCtrlEnrollmentFee->get() ?
+ (U32)mSpinEnrollmentFee->get() : 0);
+ LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID();
+
+ std::string gr_name = mGroupNameEditor->getText();
+ LLStringUtil::trim(gr_name);
+ LLGroupMgr::getInstance()->sendCreateGroupRequest(gr_name,
+ mEditCharter->getText(),
+ true,
+ insignia_id,
+ enrollment_fee,
+ mCtrlOpenEnrollment->get(),
+ false,
+ mComboMature->getCurrentIndex() == MATURE_CONTENT);
+}
+
diff --git a/indra/newview/llpanelgroupcreate.h b/indra/newview/llpanelgroupcreate.h
new file mode 100644
index 0000000000..3ae2e7f24a
--- /dev/null
+++ b/indra/newview/llpanelgroupcreate.h
@@ -0,0 +1,73 @@
+/**
+ * @file llpanelgroupcreate.h
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#ifndef LL_LLPANELGROUPCREATE_H
+#define LL_LLPANELGROUPCREATE_H
+
+#include "llpanel.h"
+
+
+// Forward declares
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLLineEditor;
+class LLTextEditor;
+class LLTextureCtrl;
+class LLScrollListCtrl;
+class LLSpinCtrl;
+
+
+class LLPanelGroupCreate : public LLPanel
+{
+public:
+ LLPanelGroupCreate();
+ virtual ~LLPanelGroupCreate();
+
+ virtual BOOL postBuild();
+
+ void onOpen(const LLSD& key);
+
+ static void refreshCreatedGroup(const LLUUID& group_id);
+
+private:
+ void addMembershipRow(const std::string &name);
+ bool confirmMatureApply(const LLSD& notification, const LLSD& response);
+ void onBtnCreate();
+ void onBackBtnClick();
+ void createGroup();
+
+ LLComboBox *mComboMature;
+ LLButton *mCreateButton;
+ LLCheckBoxCtrl *mCtrlOpenEnrollment;
+ LLCheckBoxCtrl *mCtrlEnrollmentFee;
+ LLTextEditor *mEditCharter;
+ LLTextureCtrl *mInsignia;
+ LLLineEditor *mGroupNameEditor;
+ LLScrollListCtrl *mMembershipList;
+ LLSpinCtrl *mSpinEnrollmentFee;
+};
+
+#endif // LL_LLPANELGROUPCREATE_H
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index b53cd222e7..375daf60f8 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -30,6 +30,7 @@
#include "llavatarnamecache.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llsdparam.h"
#include "lluictrlfactory.h"
#include "roles_constants.h"
@@ -303,6 +304,11 @@ void LLPanelGroupGeneral::draw()
bool LLPanelGroupGeneral::apply(std::string& mesg)
{
+ if (mGroupID.isNull())
+ {
+ return false;
+ }
+
if (!mGroupID.isNull() && mAllowEdit && mComboActiveTitle && mComboActiveTitle->isDirty())
{
LLGroupMgr::getInstance()->sendGroupTitleUpdate(mGroupID,mComboActiveTitle->getCurrentID());
@@ -312,7 +318,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
BOOL has_power_in_group = gAgent.hasPowerInGroup(mGroupID,GP_GROUP_CHANGE_IDENTITY);
- if (has_power_in_group || mGroupID.isNull())
+ if (has_power_in_group)
{
LL_INFOS() << "LLPanelGroupGeneral::apply" << LL_ENDL;
@@ -325,25 +331,6 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
return false;
}
- if (mGroupID.isNull())
- {
- // Validate the group name length.
- S32 group_name_len = mGroupNameEditor->getText().size();
- if ( group_name_len < DB_GROUP_NAME_MIN_LEN
- || group_name_len > DB_GROUP_NAME_STR_LEN)
- {
- std::ostringstream temp_error;
- temp_error << "A group name must be between " << DB_GROUP_NAME_MIN_LEN
- << " and " << DB_GROUP_NAME_STR_LEN << " characters.";
- mesg = temp_error.str();
- return false;
- }
-
- LLNotificationsUtil::add("CreateGroupCost", LLSD(), LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
-
- return false;
- }
-
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap)
{
@@ -450,37 +437,6 @@ bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLS
return ret;
}
-// static
-bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch(option)
- {
- case 0:
- {
- // Yay! We are making a new group!
- U32 enrollment_fee = (mCtrlEnrollmentFee->get() ?
- (U32) mSpinEnrollmentFee->get() : 0);
- LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID();
-
- LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
- mEditCharter->getText(),
- mCtrlShowInGroupList->get(),
- insignia_id,
- enrollment_fee,
- mCtrlOpenEnrollment->get(),
- false,
- mComboMature->getCurrentIndex() == MATURE_CONTENT);
-
- }
- break;
- case 1:
- default:
- break;
- }
- return false;
-}
-
// virtual
void LLPanelGroupGeneral::update(LLGroupChange gc)
{
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 11972bafa9..1d0789521c 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -51,7 +51,6 @@ public:
virtual bool needsApply(std::string& mesg);
virtual bool apply(std::string& mesg);
virtual void cancel();
- bool createGroupCallback(const LLSD& notification, const LLSD& response);
virtual void update(LLGroupChange gc);
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index ce6834b4b3..c63d04cd55 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -155,6 +155,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_CALLINGCARD:
case DAD_MESH:
+ case DAD_SETTINGS:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
@@ -200,9 +201,12 @@ std::string build_notice_date(const U32& the_time)
time(&t);
}
- std::string dateStr = "["+LLTrans::getString("LTimeMthNum")+"]/["
- +LLTrans::getString("LTimeDay")+"]/["
- +LLTrans::getString("LTimeYear")+"]";
+ std::string dateStr = "["+ LLTrans::getString("LTimeYear") + "]/["
+ + LLTrans::getString("LTimeMthNum") + "]/["
+ + LLTrans::getString("LTimeDay") + "] ["
+ + LLTrans::getString("LTimeHour") + "]:["
+ + LLTrans::getString("LTimeMin") + "]:["
+ + LLTrans::getString("LTimeSec") + "]";
LLSD substitution;
substitution["datetime"] = (S32) t;
LLStringUtil::format (dateStr, substitution);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 0efb234015..e3d75d5604 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1153,7 +1153,7 @@ void LLPanelGroupMembersSubTab::onInviteMember(void *userdata)
void LLPanelGroupMembersSubTab::handleInviteMember()
{
- LLFloaterGroupInvite::showForGroup(mGroupID);
+ LLFloaterGroupInvite::showForGroup(mGroupID, NULL, false);
}
void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 06bb886ae8..880323ce16 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -39,6 +39,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "lllandmarkactions.h"
+#include "llparcel.h"
#include "llslurl.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
@@ -51,7 +52,6 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
@@ -77,7 +77,7 @@ BOOL LLPanelLandmarkInfo::postBuild()
mCreator = getChild<LLTextBox>("creator");
mCreated = getChild<LLTextBox>("created");
- mLandmarkTitle = getChild<LLTextBox>("title_value");
+ mLandmarkTitle = getChild<LLLineEditor>("title_value");
mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
mNotesEditor = getChild<LLTextEditor>("notes_editor");
mFolderCombo = getChild<LLComboBox>("folder_combo");
@@ -106,6 +106,18 @@ void LLPanelLandmarkInfo::resetLocation()
// virtual
void LLPanelLandmarkInfo::setInfoType(EInfoType type)
{
+ LLUUID dest_folder;
+ setInfoType(type, dest_folder);
+}
+
+// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
+void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id)
+{
+ setInfoType(CREATE_LANDMARK, fodler_id);
+}
+
+void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id)
+{
LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
bool is_info_type_create_landmark = type == CREATE_LANDMARK;
@@ -113,6 +125,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
landmark_info_panel->setVisible(type == LANDMARK);
getChild<LLTextBox>("folder_label")->setVisible(is_info_type_create_landmark);
+ getChild<LLButton>("edit_btn")->setVisible(!is_info_type_create_landmark);
mFolderCombo->setVisible(is_info_type_create_landmark);
switch(type)
@@ -126,13 +139,10 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
mNotesEditor->setEnabled(TRUE);
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
- std::string name = parcel_mgr->getAgentParcelName();
+ LLParcel* parcel = parcel_mgr->getAgentParcel();
+ std::string name = parcel->getName();
LLVector3 agent_pos = gAgent.getPositionAgent();
- std::string desc;
- LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos);
- mNotesEditor->setText(desc);
-
if (name.empty())
{
S32 region_x = ll_round(agent_pos.mV[VX]);
@@ -147,6 +157,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
}
else
{
+ std::string desc;
LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
region_name = desc;
}
@@ -159,12 +170,31 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
mLandmarkTitleEditor->setText(name);
}
+ LLUUID owner_id = parcel->getOwnerID();
+ if (owner_id.notNull())
+ {
+ if (parcel->getIsGroupOwned())
+ {
+ std::string owner_name = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ else
+ {
+ std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ }
+ else
+ {
+ mParcelOwner->setText(getString("public"));
+ }
+
// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo()
// because we use only agent's current coordinates instead of waiting for
// remote parcel request to complete.
if (!LLLandmarkActions::landmarkAlreadyExists())
{
- createLandmark(LLUUID());
+ createLandmark(folder_id);
}
}
break;
@@ -210,6 +240,24 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
}
+ if (parcel_data.owner_id.notNull())
+ {
+ if (parcel_data.flags & 0x4) // depends onto DRTSIM-453
+ {
+ std::string owner_name = LLSLURL("group", parcel_data.owner_id, "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ else
+ {
+ std::string owner_name = LLSLURL("agent", parcel_data.owner_id, "inspect").getSLURLString();
+ mParcelOwner->setText(owner_name);
+ }
+ }
+ else
+ {
+ mParcelOwner->setText(getString("public"));
+ }
+
LLSD info;
info["update_verbs"] = true;
info["global_x"] = parcel_data.global_x;
@@ -264,7 +312,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
}
else
{
- mOwner->setText(getString("public"));
+ std::string public_str = getString("public");
+ mOwner->setText(public_str);
}
//////////////////
@@ -311,6 +360,7 @@ void LLPanelLandmarkInfo::toggleLandmarkEditMode(BOOL enabled)
mNotesEditor->setReadOnly(!enabled);
mFolderCombo->setVisible(enabled);
getChild<LLTextBox>("folder_label")->setVisible(enabled);
+ getChild<LLButton>("edit_btn")->setVisible(!enabled);
// HACK: To change the text color in a text editor
// when it was enabled/disabled we set the text once again.
@@ -357,7 +407,7 @@ void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
// If no parcel exists use the region name instead.
if (name.empty())
{
- name = mRegionName->getText();
+ name = mRegionTitle;
}
}
@@ -465,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
return left.second < right.second;
}
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
+void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
{
LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
@@ -478,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
items,
LLInventoryModel::EXCLUDE_TRASH,
is_category);
+}
- // Add the "My Favorites" category.
- LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
- if (!favorites_cat)
- {
- LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
- }
- else
- {
- cats.push_back(favorites_cat);
- }
+/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id)
+{
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ mItem->setParent(mNewParentId);
+ mItem->updateParentOnServer(FALSE);
+
+ gInventory.updateItem(mItem);
+ gInventory.notifyObservers();
}
diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h
index 01a6fd6b3d..f727f286b5 100644
--- a/indra/newview/llpanellandmarkinfo.h
+++ b/indra/newview/llpanellandmarkinfo.h
@@ -28,6 +28,7 @@
#define LL_LLPANELLANDMARKINFO_H
#include "llpanelplaceinfo.h"
+#include "llinventorymodel.h"
class LLComboBox;
class LLLineEditor;
@@ -43,8 +44,12 @@ public:
/*virtual*/ void resetLocation();
+ // If landmark doesn't exists, will create it at default folder
/*virtual*/ void setInfoType(EInfoType type);
+ // Sets CREATE_LANDMARK infotype and creates landmark at desired folder
+ void setInfoAndCreateLandmark(const LLUUID& fodler_id);
+
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
// Displays landmark owner, creator and creation date info.
@@ -59,22 +64,41 @@ public:
// Select current landmark folder in combobox.
BOOL setLandmarkFolder(const LLUUID& id);
- // Create a landmark for the current location
- // in a folder specified by folder_id.
- void createLandmark(const LLUUID& folder_id);
-
+ typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
+ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
private:
+ // Create a landmark for the current location
+ // in a folder specified by folder_id.
+ // Expects title and description to be initialized
+ void createLandmark(const LLUUID& folder_id);
+
+ // If landmark doesn't exists, will create it at specified folder
+ void setInfoType(EInfoType type, const LLUUID &folder_id);
+
void populateFoldersList();
LLTextBox* mOwner;
LLTextBox* mCreator;
LLTextBox* mCreated;
- LLTextBox* mLandmarkTitle;
+ LLLineEditor* mLandmarkTitle;
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLComboBox* mFolderCombo;
};
+class LLUpdateLandmarkParent : public LLInventoryCallback
+{
+public:
+ LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
+ mItem(item),
+ mNewParentId(new_parent)
+ {};
+ /* virtual */ void fire(const LLUUID& inv_item_id);
+
+private:
+ LLPointer<LLViewerInventoryItem> mItem;
+ LLUUID mNewParentId;
+};
#endif // LL_LLPANELLANDMARKINFO_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index cd1dc0f070..e698a61fef 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -36,12 +36,11 @@
#include "llregionhandle.h"
#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentpicksinfo.h"
#include "llagentui.h"
+#include "llavataractions.h"
#include "llcallbacklist.h"
-#include "lldndbutton.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llfolderviewitem.h"
@@ -60,15 +59,8 @@
// Not yet implemented; need to remove buildPanel() from constructor when we switch
//static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks");
-static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn";
-static const std::string ADD_BUTTON_NAME = "add_btn";
-static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn";
-static const std::string TRASH_BUTTON_NAME = "trash_btn";
-
-
// helper functions
static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string);
-static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list);
static void collapse_all_folders(LLFolderView* root_folder);
static void expand_all_folders(LLFolderView* root_folder);
static bool has_expanded_folders(LLFolderView* root_folder);
@@ -149,69 +141,37 @@ void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
}
}
-/**
- * Bridge to support knowing when the inventory has changed to update Landmarks tab
- * ShowFolderState filter setting to show all folders when the filter string is empty and
- * empty folder message when Landmarks inventory category has no children.
- * Ensures that "Landmarks" folder in the Library is open on strart up.
- */
-class LLLandmarksPanelObserver : public LLInventoryObserver
-{
-public:
- LLLandmarksPanelObserver(LLLandmarksPanel* lp)
- : mLP(lp),
- mIsLibraryLandmarksOpen(false)
- {}
- virtual ~LLLandmarksPanelObserver() {}
- /*virtual*/ void changed(U32 mask);
-
-private:
- LLLandmarksPanel* mLP;
- bool mIsLibraryLandmarksOpen;
-};
-
-void LLLandmarksPanelObserver::changed(U32 mask)
+LLLandmarksPanel::LLLandmarksPanel()
+ : LLPanelPlacesTab()
+ , mLandmarksInventoryPanel(NULL)
+ , mCurrentSelectedList(NULL)
+ , mGearFolderMenu(NULL)
+ , mGearLandmarkMenu(NULL)
+ , mSortingMenu(NULL)
+ , mAddMenu(NULL)
+ , isLandmarksPanel(true)
{
- mLP->updateShowFolderState();
-
- LLPlacesInventoryPanel* library = mLP->getLibraryInventoryPanel();
- if (!mIsLibraryLandmarksOpen && library)
- {
- // Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
- const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
- if (landmarks_cat.notNull())
- {
- LLOpenFolderByID opener(landmarks_cat);
- library->getRootFolder()->applyFunctorRecursively(opener);
- mIsLibraryLandmarksOpen = opener.isFolderOpen();
- }
- }
+ buildFromFile("panel_landmarks.xml");
}
-LLLandmarksPanel::LLLandmarksPanel()
+LLLandmarksPanel::LLLandmarksPanel(bool is_landmark_panel)
: LLPanelPlacesTab()
- , mFavoritesInventoryPanel(NULL)
, mLandmarksInventoryPanel(NULL)
- , mMyInventoryPanel(NULL)
- , mLibraryInventoryPanel(NULL)
, mCurrentSelectedList(NULL)
- , mListCommands(NULL)
- , mGearButton(NULL)
, mGearFolderMenu(NULL)
, mGearLandmarkMenu(NULL)
+ , mSortingMenu(NULL)
+ , mAddMenu(NULL)
+ , isLandmarksPanel(is_landmark_panel)
{
- mInventoryObserver = new LLLandmarksPanelObserver(this);
- gInventory.addObserver(mInventoryObserver);
-
- buildFromFile( "panel_landmarks.xml");
+ if (is_landmark_panel)
+ {
+ buildFromFile("panel_landmarks.xml");
+ }
}
LLLandmarksPanel::~LLLandmarksPanel()
{
- if (gInventory.containsObserver(mInventoryObserver))
- {
- gInventory.removeObserver(mInventoryObserver);
- }
}
BOOL LLLandmarksPanel::postBuild()
@@ -221,11 +181,7 @@ BOOL LLLandmarksPanel::postBuild()
// mast be called before any other initXXX methods to init Gear menu
initListCommandsHandlers();
-
- initFavoritesInventoryPanel();
initLandmarksInventoryPanel();
- initMyInventoryPanel();
- initLibraryInventoryPanel();
return TRUE;
}
@@ -233,30 +189,10 @@ BOOL LLLandmarksPanel::postBuild()
// virtual
void LLLandmarksPanel::onSearchEdit(const std::string& string)
{
- // give FolderView a chance to be refreshed. So, made all accordions visible
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- LLAccordionCtrlTab* tab = *iter;
- tab->setVisible(TRUE);
-
- // expand accordion to see matched items in each one. See EXT-2014.
- if (string != "")
- {
- tab->changeOpenClose(false);
- }
-
- LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
- if (NULL == inventory_list) continue;
-
- filter_list(inventory_list, string);
- }
+ filter_list(mCurrentSelectedList, string);
if (sFilterSubString != string)
sFilterSubString = string;
-
- // show all folders in Landmarks Accordion for empty filter
- // only if Landmarks inventory folder is not empty
- updateShowFolderState();
}
// virtual
@@ -268,11 +204,6 @@ void LLLandmarksPanel::onShowOnMap()
return;
}
- // Disable the "Map" button because loading landmark can take some time.
- // During this time the button is useless. It will be enabled on callback finish
- // or upon switching to other item.
- mShowOnMapBtn->setEnabled(FALSE);
-
doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1));
}
@@ -297,6 +228,12 @@ void LLLandmarksPanel::onTeleport()
}
}
+/*virtual*/
+void LLLandmarksPanel::onRemoveSelected()
+{
+ onClipboardAction("delete");
+}
+
// virtual
bool LLLandmarksPanel::isSingleItemSelected()
{
@@ -316,86 +253,55 @@ bool LLLandmarksPanel::isSingleItemSelected()
}
// virtual
-void LLLandmarksPanel::updateVerbs()
-{
- if (!isTabVisible())
- return;
-
- bool landmark_selected = isLandmarkSelected();
- mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport"));
- mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info"));
- mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map"));
-
- // TODO: mantipov: Uncomment when mShareBtn is supported
- // Share button should be enabled when neither a folder nor a landmark is selected
- //mShareBtn->setEnabled(NULL != current_item);
-
- updateListCommands();
+LLToggleableMenu* LLLandmarksPanel::getSelectionMenu()
+{
+ LLToggleableMenu* menu = mGearFolderMenu;
+
+ if (mCurrentSelectedList)
+ {
+ LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
+ if (!listenerp)
+ return menu;
+
+ if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ menu = mGearLandmarkMenu;
+ }
+ }
+ return menu;
}
-void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
+// virtual
+LLToggleableMenu* LLLandmarksPanel::getSortingMenu()
{
- if (user_action && (items.size() > 0))
- {
- deselectOtherThan(inventory_list);
- mCurrentSelectedList = inventory_list;
- }
- updateVerbs();
+ return mSortingMenu;
}
-void LLLandmarksPanel::onSelectorButtonClicked()
+// virtual
+LLToggleableMenu* LLLandmarksPanel::getCreateMenu()
{
- // TODO: mantipov: update getting of selected item
- // TODO: bind to "i" button
- LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
- if (!cur_item) return;
-
- LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
- if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
- LLSD key;
- key["type"] = "landmark";
- key["id"] = listenerp->getUUID();
-
- LLFloaterSidePanelContainer::showPanel("places", key);
- }
+ return mAddMenu;
}
-void LLLandmarksPanel::updateShowFolderState()
+void LLLandmarksPanel::updateVerbs()
{
- bool show_all_folders = mLandmarksInventoryPanel->getFilterSubString().empty();
- if (show_all_folders)
+ if (sRemoveBtn)
{
- show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
+ sRemoveBtn->setEnabled(isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()));
}
-
- mLandmarksInventoryPanel->setShowFolderState(show_all_folders ?
- LLInventoryFilter::SHOW_ALL_FOLDERS :
- LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS
- );
}
void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)
{
- if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus))
- {
- return;
- }
-
- if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus))
- {
+ if (!mCurrentSelectedList)
return;
- }
- if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus))
- {
- return;
- }
-
- if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus))
- {
+ LLFolderView* root = mCurrentSelectedList->getRootFolder();
+ LLFolderViewItem* item = mCurrentSelectedList->getItemByID(obj_id);
+ if (!item)
return;
- }
+ root->setSelection(item, FALSE, take_keyboard_focus);
+ root->scrollToShowSelection();
}
//////////////////////////////////////////////////////////////////////////
@@ -414,18 +320,6 @@ bool LLLandmarksPanel::isFolderSelected() const
return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);
}
-bool LLLandmarksPanel::isReceivedFolderSelected() const
-{
- // Received Folder can be only in Landmarks accordion
- if (mCurrentSelectedList != mLandmarksInventoryPanel) return false;
-
- // *TODO: it should be filled with logic when EXT-976 is done.
-
- LL_WARNS() << "Not implemented yet until EXT-976 is done." << LL_ENDL;
-
- return false;
-}
-
void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
{
LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
@@ -455,36 +349,6 @@ LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem()
}
-LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
- const std::string& tab_name,
- const LLUUID& obj_id,
- BOOL take_keyboard_focus) const
-{
- if (!inventory_list)
- return NULL;
-
- LLFolderView* root = inventory_list->getRootFolder();
-
- LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
- if (!item)
- return NULL;
-
- LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name);
- if (!tab->isExpanded())
- {
- tab->changeOpenClose(false);
- }
-
- root->setSelection(item, FALSE, take_keyboard_focus);
-
- LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
- LLRect screen_rc;
- localRectToScreen(item->getRect(), &screen_rc);
- accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
-
- return item;
-}
-
void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
{
if(!panel) return;
@@ -500,19 +364,29 @@ void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
}
}
+void LLLandmarksPanel::resetSelection()
+{
+}
+
// virtual
void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
{
//this function will be called after user will try to create a pick for selected landmark.
// We have to make request to sever to get parcel_id and snaption_id.
- if(isLandmarkSelected())
+ if(mCreatePickItemId.notNull())
{
- LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
- if (!cur_item) return;
- LLUUID id = cur_item->getUUID();
- LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
- doActionOnCurSelectedLandmark(boost::bind(
- &LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
+ LLInventoryItem* inv_item = gInventory.getItem(mCreatePickItemId);
+
+ if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ // we are processing response for doCreatePick, landmark should be already loaded
+ LLLandmark* landmark = LLLandmarkActions::getLandmark(inv_item->getUUID());
+ if (landmark)
+ {
+ doProcessParcelInfo(landmark, inv_item, parcel_data);
+ }
+ }
+ mCreatePickItemId.setNull();
}
}
@@ -537,16 +411,6 @@ void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason)
// PRIVATE METHODS
//////////////////////////////////////////////////////////////////////////
-void LLLandmarksPanel::initFavoritesInventoryPanel()
-{
- mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
-
- initLandmarksPanel(mFavoritesInventoryPanel);
- mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
-
- initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
-}
-
void LLLandmarksPanel::initLandmarksInventoryPanel()
{
mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list");
@@ -558,40 +422,14 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
// subscribe to have auto-rename functionality while creating New Folder
mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
- mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true);
-}
-
-void LLLandmarksPanel::initMyInventoryPanel()
-{
- mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list");
-
- initLandmarksPanel(mMyInventoryPanel);
-
- initAccordion("tab_inventory", mMyInventoryPanel, false);
-}
-
-void LLLandmarksPanel::initLibraryInventoryPanel()
-{
- mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list");
-
- initLandmarksPanel(mLibraryInventoryPanel);
-
- // We want to fetch only "Landmarks" category from the library.
- const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
- if (landmarks_cat.notNull())
- {
- LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
- }
-
- // Expanding "Library" tab for new users who have no landmarks in "My Inventory".
- initAccordion("tab_library", mLibraryInventoryPanel, true);
+ mCurrentSelectedList = mLandmarksInventoryPanel;
}
void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
{
inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
- inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
+ inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::updateVerbs, this));
inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
@@ -609,86 +447,10 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
inventory_list->saveFolderState();
}
-LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab)
-{
- LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
-
- mAccordionTabs.push_back(accordion_tab);
- accordion_tab->setDropDownStateChangedCallback(
- boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
- accordion_tab->setDisplayChildren(expand_tab);
- return accordion_tab;
-}
-
-void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list)
-{
- bool expanded = param.asBoolean();
-
- if(!expanded && (mCurrentSelectedList == inventory_list))
- {
- inventory_list->getRootFolder()->clearSelection();
-
- mCurrentSelectedList = NULL;
- updateVerbs();
- }
-
- // Start background fetch, mostly for My Inventory and Library
- if (expanded)
- {
- const LLUUID &cat_id = inventory_list->getRootFolderID();
- // Just because the category itself has been fetched, doesn't mean its child folders have.
- /*
- if (!gInventory.isCategoryComplete(cat_id))
- */
- {
- LLInventoryModelBackgroundFetch::instance().start(cat_id);
- }
-
- // Apply filter substring because it might have been changed
- // while accordion was closed. See EXT-3714.
- filter_list(inventory_list, sFilterSubString);
- }
-}
-
-void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list)
-{
- if (inventory_list != mFavoritesInventoryPanel)
- {
- mFavoritesInventoryPanel->clearSelection();
- }
-
- if (inventory_list != mLandmarksInventoryPanel)
- {
- mLandmarksInventoryPanel->clearSelection();
- }
- if (inventory_list != mMyInventoryPanel)
- {
- mMyInventoryPanel->clearSelection();
- }
- if (inventory_list != mLibraryInventoryPanel)
- {
- mLibraryInventoryPanel->clearSelection();
- }
-}
// List Commands Handlers
void LLLandmarksPanel::initListCommandsHandlers()
{
- mListCommands = getChild<LLPanel>("bottom_panel");
-
- mGearButton = getChild<LLMenuButton>(OPTIONS_BUTTON_NAME);
- mGearButton->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this));
-
- mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this));
-
- LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME);
- trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this
- , _4 // BOOL drop
- , _5 // EDragAndDropType cargo_type
- , _6 // void* cargo_data
- , _7 // EAcceptance* accept
- ));
-
mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2));
mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2));
mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2));
@@ -697,23 +459,16 @@ void LLLandmarksPanel::initListCommandsHandlers()
mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2));
mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_sorting.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mAddMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2));
mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2));
- mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME));
-}
-
-
-void LLLandmarksPanel::updateListCommands()
-{
- bool add_folder_enabled = isActionEnabled("category");
- bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected());
-
- // keep Options & Add Landmark buttons always enabled
- mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled);
- mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled);
+ // show menus even if all items are disabled
+ mGearLandmarkMenu->setAlwaysShowMenu(TRUE);
+ mGearFolderMenu->setAlwaysShowMenu(TRUE);
+ mAddMenu->setAlwaysShowMenu(TRUE);
}
void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)
@@ -721,43 +476,6 @@ void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)
onMenuVisibilityChange(menu, LLSD().with("visibility", true));
}
-void LLLandmarksPanel::onActionsButtonClick()
-{
- LLToggleableMenu* menu = mGearFolderMenu;
-
- if(mCurrentSelectedList)
- {
- LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
- if(!listenerp)
- return;
-
- if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
- menu = mGearLandmarkMenu;
- }
- }
-
- mGearButton->setMenu(menu);
-}
-
-void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
-{
- if (menu)
- {
- menu->buildDrawLabels();
- menu->updateParent(LLMenuGL::sMenuContainer);
- menu->arrangeAndClear();
-
- LLView* spawning_view = getChild<LLView>(spawning_view_name);
-
- S32 menu_x, menu_y;
- //show menu in co-ordinates of panel
- spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
- menu_y += menu->getRect().getHeight();
- LLMenuGL::showPopup(this, menu, menu_x, menu_y);
- }
-}
-
void LLLandmarksPanel::onTrashButtonClick() const
{
onClipboardAction("delete");
@@ -769,7 +487,8 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
LLFolderViewItem* item = getCurSelectedItem();
std::string command_name = userdata.asString();
- if("add_landmark" == command_name)
+ if("add_landmark" == command_name
+ || "add_landmark_root" == command_name)
{
LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
if(landmark)
@@ -778,7 +497,20 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
}
else
{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+ LLSD args;
+ args["type"] = "create_landmark";
+ if ("add_landmark" == command_name
+ && view_model->getInventoryType() == LLInventoryType::IT_CATEGORY)
+ {
+ args["dest_folder"] = view_model->getUUID();
+ }
+ if ("add_landmark_root" == command_name
+ && mCurrentSelectedList == mLandmarksInventoryPanel)
+ {
+ args["dest_folder"] = mLandmarksInventoryPanel->getRootFolderID();
+ }
+ // else will end up in favorites
+ LLFloaterReg::showInstance("add_landmark", args);
}
}
else if ("category" == command_name)
@@ -810,13 +542,14 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
-
- if (mMyLandmarksAccordionTab)
- {
- mMyLandmarksAccordionTab->changeOpenClose(false);
- }
}
}
+ else if ("category_root" == command_name)
+ {
+ //in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
+ menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
+ }
}
void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
@@ -850,27 +583,11 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
if ("expand_all" == command_name)
{
- expand_all_folders(mFavoritesInventoryPanel->getRootFolder());
- expand_all_folders(mLandmarksInventoryPanel->getRootFolder());
- expand_all_folders(mMyInventoryPanel->getRootFolder());
- expand_all_folders(mLibraryInventoryPanel->getRootFolder());
-
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- (*iter)->changeOpenClose(false);
- }
+ expand_all_folders(mCurrentSelectedList->getRootFolder());
}
else if ("collapse_all" == command_name)
{
- collapse_all_folders(mFavoritesInventoryPanel->getRootFolder());
- collapse_all_folders(mLandmarksInventoryPanel->getRootFolder());
- collapse_all_folders(mMyInventoryPanel->getRootFolder());
- collapse_all_folders(mLibraryInventoryPanel->getRootFolder());
-
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- (*iter)->changeOpenClose(true);
- }
+ collapse_all_folders(mCurrentSelectedList->getRootFolder());
}
else if ("sort_by_date" == command_name)
{
@@ -878,8 +595,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
sorting_order=!sorting_order;
gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order);
updateSortOrder(mLandmarksInventoryPanel, sorting_order);
- updateSortOrder(mMyInventoryPanel, sorting_order);
- updateSortOrder(mLibraryInventoryPanel, sorting_order);
}
else
{
@@ -911,51 +626,21 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
? mCurrentSelectedList->getRootFolder()
: NULL;
+ bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1;
+
if ("collapse_all" == command_name)
{
- bool disable_collapse_all = !has_expanded_folders(mFavoritesInventoryPanel->getRootFolder())
- && !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder())
- && !has_expanded_folders(mMyInventoryPanel->getRootFolder())
- && !has_expanded_folders(mLibraryInventoryPanel->getRootFolder());
- if (disable_collapse_all)
- {
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- if ((*iter)->isExpanded())
- {
- disable_collapse_all = false;
- break;
- }
- }
- }
-
- return !disable_collapse_all;
+ return has_expanded_folders(mCurrentSelectedList->getRootFolder());
}
else if ("expand_all" == command_name)
{
- bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder())
- && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder())
- && !has_collapsed_folders(mMyInventoryPanel->getRootFolder())
- && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder());
- if (disable_expand_all)
- {
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- if (!(*iter)->isExpanded())
- {
- disable_expand_all = false;
- break;
- }
- }
- }
-
- return !disable_expand_all;
+ return has_collapsed_folders(mCurrentSelectedList->getRootFolder());
}
else if ("sort_by_date" == command_name)
{
- // disable "sort_by_date" for Favorites accordion because
+ // disable "sort_by_date" for Favorites tab because
// it has its own items order. EXT-1758
- if (mCurrentSelectedList == mFavoritesInventoryPanel)
+ if (!isLandmarksPanel)
{
return false;
}
@@ -972,6 +657,11 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
+ if (selected_uuids.empty())
+ {
+ return false;
+ }
+
// Allow to execute the command only if it can be applied to all selected items.
for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
{
@@ -992,7 +682,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
)
{
// disable some commands for multi-selection. EXT-1757
- bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1;
if (!is_single_selection)
{
return false;
@@ -1011,9 +700,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
// Disable "Show on Map" if landmark loading is in progress.
return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid);
- }
- else if ("rename" == command_name)
- {
+ }
+ else if ("rename" == command_name)
+ {
LLFolderViewItem* selected_item = getCurSelectedItem();
if (!selected_item) return false;
@@ -1022,16 +711,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
return true;
}
- else if("category" == command_name)
- {
- // we can add folder only in Landmarks Accordion
- if (mCurrentSelectedList == mLandmarksInventoryPanel)
- {
- // ... but except Received folder
- return !isReceivedFolderSelected();
- }
- //"Add a folder" is enabled by default (case when My Landmarks is empty)
- else return true;
+ if ("category_root" == command_name || "category" == command_name)
+ {
+ // we can add folder only in Landmarks tab
+ return isLandmarksPanel;
}
else if("create_pick" == command_name)
{
@@ -1045,6 +728,78 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
}
return false;
}
+ else if ("add_landmark" == command_name)
+ {
+ if (!is_single_selection)
+ {
+ return false;
+ }
+
+ LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+ if (!view_model || view_model->getInventoryType() != LLInventoryType::IT_CATEGORY)
+ {
+ return false;
+ }
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+ if (landmark)
+ {
+ //already exists
+ return false;
+ }
+ return true;
+ }
+ else if ("add_landmark_root" == command_name)
+ {
+ LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+ if (landmark)
+ {
+ //already exists
+ return false;
+ }
+ return true;
+ }
+ else if ("share" == command_name)
+ {
+ if (!mCurrentSelectedList)
+ {
+ return false;
+ }
+ if (!LLAvatarActions::canShareSelectedItems(mCurrentSelectedList))
+ {
+ return false;
+ }
+ return true;
+ }
+ else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites")
+ {
+ LLFolderViewModelItemInventory* cur_item_model = getCurSelectedViewModelItem();
+ if (cur_item_model)
+ {
+ LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_FAVORITE : LLFolderType::FT_LANDMARK;
+ if (!gInventory.isObjectDescendentOf(cur_item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type)))
+ {
+ return false;
+ }
+
+ if (root_folder_view)
+ {
+ std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ {
+ LLFolderViewItem* item = *iter;
+ if (!item) return false;
+
+ cur_item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
+ if (!cur_item_model || cur_item_model->getInventoryType() != LLInventoryType::IT_LANDMARK)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
else
{
LL_WARNS() << "Unprocessed command has come: " << command_name << LL_ENDL;
@@ -1070,12 +825,42 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)
}
else if ("create_pick" == command_name)
{
- doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1));
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+ if (cur_item)
+ {
+ doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1, cur_item->getUUID()));
+ }
}
+ else if ("share" == command_name && mCurrentSelectedList)
+ {
+ LLAvatarActions::shareWithAvatars(mCurrentSelectedList);
+ }
else if ("restore" == command_name && mCurrentSelectedList)
{
mCurrentSelectedList->doToSelected(userdata);
}
+ else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites")
+ {
+ LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL;
+ if (root_folder_view)
+ {
+ LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_LANDMARK : LLFolderType::FT_FAVORITE;
+ std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ {
+ LLFolderViewItem* item = *iter;
+ if (item)
+ {
+ LLFolderViewModelItemInventory* item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
+ if (item_model)
+ {
+ change_item_parent(item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type));
+ }
+ }
+ }
+ }
+
+ }
}
void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
@@ -1142,29 +927,17 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
if (!item) return false;
- // nothing can be modified in Library
- if (mLibraryInventoryPanel == mCurrentSelectedList) return false;
-
bool can_be_modified = false;
// landmarks can be modified in any other accordion...
if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
can_be_modified = true;
-
- // we can modify landmarks anywhere except paste to My Inventory
- if ("paste" == command_name)
- {
- can_be_modified = (mCurrentSelectedList != mMyInventoryPanel);
- }
}
else
{
// ...folders only in the Landmarks accordion...
- can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList;
-
- // ...except "Received" folder
- can_be_modified &= !isReceivedFolderSelected();
+ can_be_modified = isLandmarksPanel;
}
// then ask LLFolderView permissions
@@ -1281,12 +1054,10 @@ void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark)
LLFloaterReg::showInstance("world_map", "center");
}
- mShowOnMapBtn->setEnabled(TRUE);
mGearLandmarkMenu->setItemEnabled("show_on_map", TRUE);
}
void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
- LLFolderViewItem* cur_item,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
@@ -1315,7 +1086,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLPickData data;
data.pos_global = landmark_global_pos;
- data.name = cur_item->getName();
+ data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
@@ -1335,11 +1106,13 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
panel_pick, panel_places,params));
}
-void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
+void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
{
LLViewerRegion* region = gAgent.getRegion();
if (!region) return;
+ mCreatePickItemId = item_id;
+
LLGlobalVec pos_global;
LLUUID region_id;
landmark->getGlobalPos(pos_global);
@@ -1392,27 +1165,12 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
inventory_list->setFilterSubString(string);
}
-static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
-{
- LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
- if (category)
- {
- return category->getDescendentCount() > 0;
- }
-
- return false;
-}
-
static void collapse_all_folders(LLFolderView* root_folder)
{
if (!root_folder)
return;
root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
-
- // The top level folder is invisible, it must be open to
- // display its sub-folders.
- root_folder->openTopLevelFolders();
root_folder->arrangeAll();
}
@@ -1479,4 +1237,31 @@ void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled)
}
}
}
+
+LLFavoritesPanel::LLFavoritesPanel()
+ : LLLandmarksPanel(false)
+{
+ buildFromFile("panel_favorites.xml");
+}
+
+BOOL LLFavoritesPanel::postBuild()
+{
+ if (!gInventory.isInventoryUsable())
+ return FALSE;
+
+ // mast be called before any other initXXX methods to init Gear menu
+ LLLandmarksPanel::initListCommandsHandlers();
+
+ initFavoritesInventoryPanel();
+
+ return TRUE;
+}
+
+void LLFavoritesPanel::initFavoritesInventoryPanel()
+{
+ mCurrentSelectedList = getChild<LLPlacesInventoryPanel>("favorites_list");
+
+ LLLandmarksPanel::initLandmarksPanel(mCurrentSelectedList);
+ mCurrentSelectedList->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
+}
// EOF
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index c11cbe05ae..d7408269b5 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -50,81 +50,69 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
{
public:
LLLandmarksPanel();
+ LLLandmarksPanel(bool is_landmark_panel);
virtual ~LLLandmarksPanel();
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onSearchEdit(const std::string& string);
- /*virtual*/ void onShowOnMap();
- /*virtual*/ void onShowProfile();
- /*virtual*/ void onTeleport();
- /*virtual*/ void updateVerbs();
- /*virtual*/ bool isSingleItemSelected();
+ BOOL postBuild() override;
+ void onSearchEdit(const std::string& string) override;
+ void onShowOnMap() override;
+ void onShowProfile() override;
+ void onTeleport() override;
+ void onRemoveSelected() override;
+ void updateVerbs() override;
+ bool isSingleItemSelected() override;
+
+ LLToggleableMenu* getSelectionMenu() override;
+ LLToggleableMenu* getSortingMenu() override;
+ LLToggleableMenu* getCreateMenu() override;
+
+ /**
+ * Processes drag-n-drop of the Landmarks and folders into trash button.
+ */
+ bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override;
- void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- void onSelectorButtonClicked();
void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list)
{
mCurrentSelectedList = inventory_list;
}
/**
- * Update filter ShowFolderState setting to show empty folder message
- * if Landmarks inventory folder is empty.
- */
- void updateShowFolderState();
-
- /**
* Selects item with "obj_id" in one of accordion tabs.
*/
void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
- LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; }
-
void updateMenuVisibility(LLUICtrl* menu);
+ void doCreatePick(LLLandmark* landmark, const LLUUID &item_id );
+
+ void resetSelection();
+
protected:
/**
* @return true - if current selected panel is not null and selected item is a landmark
*/
bool isLandmarkSelected() const;
bool isFolderSelected() const;
- bool isReceivedFolderSelected() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
- /**
- * Selects item with "obj_id" in "inventory_list" and scrolls accordion
- * scrollbar to show the item.
- * Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
- */
- LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
- const std::string& tab_name,
- const LLUUID& obj_id,
- BOOL take_keyboard_focus) const;
-
void updateSortOrder(LLInventoryPanel* panel, bool byDate);
//LLRemoteParcelInfoObserver interface
- /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void setParcelID(const LLUUID& parcel_id);
- /*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
+ void processParcelInfo(const LLParcelData& parcel_data) override;
+ void setParcelID(const LLUUID& parcel_id) override;
+ void setErrorStatus(S32 status, const std::string& reason) override;
+
+ // List Commands Handlers
+ void initListCommandsHandlers();
+ void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
+
+ LLPlacesInventoryPanel* mCurrentSelectedList;
private:
- void initFavoritesInventoryPanel();
void initLandmarksInventoryPanel();
- void initMyInventoryPanel();
- void initLibraryInventoryPanel();
- void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
- LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);
- void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);
- void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list);
- // List Commands Handlers
- void initListCommandsHandlers();
- void updateListCommands();
- void onActionsButtonClick();
- void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
void onTrashButtonClick() const;
void onAddAction(const LLSD& command_name) const;
void onClipboardAction(const LLSD& command_name) const;
@@ -151,38 +139,33 @@ private:
void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
- * Processes drag-n-drop of the Landmarks and folders into trash button.
- */
- bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
- /**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
*/
void doShowOnMap(LLLandmark* landmark);
void doProcessParcelInfo(LLLandmark* landmark,
- LLFolderViewItem* cur_item,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data);
- void doCreatePick(LLLandmark* landmark);
private:
- LLPlacesInventoryPanel* mFavoritesInventoryPanel;
LLPlacesInventoryPanel* mLandmarksInventoryPanel;
- LLPlacesInventoryPanel* mMyInventoryPanel;
- LLPlacesInventoryPanel* mLibraryInventoryPanel;
- LLMenuButton* mGearButton;
LLToggleableMenu* mGearLandmarkMenu;
LLToggleableMenu* mGearFolderMenu;
- LLMenuGL* mMenuAdd;
- LLPlacesInventoryPanel* mCurrentSelectedList;
- LLInventoryObserver* mInventoryObserver;
+ LLToggleableMenu* mSortingMenu;
+ LLToggleableMenu* mAddMenu;
- LLPanel* mListCommands;
+ bool isLandmarksPanel;
- typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
- accordion_tabs_t mAccordionTabs;
+ LLUUID mCreatePickItemId; // item we requested a pick for
+};
- LLAccordionCtrlTab* mMyLandmarksAccordionTab;
+
+class LLFavoritesPanel : public LLLandmarksPanel
+{
+public:
+ LLFavoritesPanel();
+
+ BOOL postBuild() override;
+ void initFavoritesInventoryPanel();
};
#endif //LL_LLPANELLANDMARKS_H
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index e253557797..3964dc075c 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -41,7 +41,6 @@
#include "llcommandhandler.h" // for secondlife:///app/login/
#include "llcombobox.h"
#include "llviewercontrol.h"
-#include "llfloaterpreference.h"
#include "llfocusmgr.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
@@ -77,6 +76,60 @@ LLPanelLogin *LLPanelLogin::sInstance = NULL;
BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
BOOL LLPanelLogin::sCredentialSet = FALSE;
+// Helper functions
+
+LLPointer<LLCredential> load_user_credentials(std::string &user_key)
+{
+ if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
+ {
+ // user_key should be of "name Resident" format
+ return gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
+ }
+ else
+ {
+ // legacy (or legacy^2, since it also tries to load from settings)
+ return gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ }
+}
+
+// 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:
@@ -168,6 +221,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mCallback(callback),
mCallbackData(cb_data),
mListener(new LLPanelLoginListener(this)),
+ mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
@@ -186,7 +240,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
login_holder->addChild(this);
}
- if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ if (mFirstLoginThisInstall)
{
buildFromFile( "panel_login_first.xml");
}
@@ -206,35 +260,39 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
- LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
- updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
- favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
- favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
-
- LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
-
- // Load all of the grids, sorted, and then add a bar and the current grid at the top
- server_choice_combo->removeall();
-
- std::string current_grid = LLGridManager::getInstance()->getGrid();
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
- grid_choice != known_grids.end();
- grid_choice++)
- {
- if (!grid_choice->first.empty() && current_grid != grid_choice->first)
- {
- LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL;
- server_choice_combo->add(grid_choice->second, grid_choice->first);
- }
- }
- server_choice_combo->sortByName();
- LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;
- server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
- current_grid,
- ADD_TOP);
- server_choice_combo->selectFirstItem();
+ std::string current_grid = LLGridManager::getInstance()->getGrid();
+ if (!mFirstLoginThisInstall)
+ {
+ LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
+
+ LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
+
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ server_choice_combo->removeall();
+
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+ for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
+ grid_choice != known_grids.end();
+ grid_choice++)
+ {
+ if (!grid_choice->first.empty() && current_grid != grid_choice->first)
+ {
+ LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
+ server_choice_combo->add(grid_choice->second, grid_choice->first);
+ }
+ }
+ server_choice_combo->sortByName();
+
+ LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
+ server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
+ current_grid,
+ ADD_TOP);
+ server_choice_combo->selectFirstItem();
+ }
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
@@ -279,10 +337,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLButton* def_btn = getChild<LLButton>("connect_btn");
setDefaultBtn(def_btn);
- std::string channel = LLVersionInfo::getChannel();
+ std::string channel = LLVersionInfo::instance().getChannel();
std::string version = llformat("%s (%d)",
- LLVersionInfo::getShortVersion().c_str(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getShortVersion().c_str(),
+ LLVersionInfo::instance().getBuild());
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
@@ -297,14 +355,30 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
loadLoginPage();
LLComboBox* username_combo(getChild<LLComboBox>("username_combo"));
- username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
+ username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::onUserNameTextEnty, this));
// STEAM-14: When user presses Enter with this field in focus, initiate login
- username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onUserListCommit, this));
+ 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));
+ }
}
void LLPanelLogin::addFavoritesToStartLocation()
{
+ if (mFirstLoginThisInstall)
+ {
+ // first login panel has no favorites, just update name length and buttons
+ std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
+ mUsernameLength = user_defined_name.length();
+ updateLoginButtons();
+ return;
+ }
+
// Clear the combo.
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
if (!combo) return;
@@ -316,14 +390,14 @@ void LLPanelLogin::addFavoritesToStartLocation()
// Load favorites into the combo.
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
+ LLStringUtil::trim(user_defined_name);
LLStringUtil::toLower(user_defined_name);
- std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
mUsernameLength = user_defined_name.length();
updateLoginButtons();
- std::string::size_type index = user_defined_name.find(' ');
+ std::string::size_type index = user_defined_name.find_first_of(" ._");
if (index != std::string::npos)
{
std::string username = user_defined_name.substr(0, index);
@@ -332,6 +406,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
{
user_defined_name = username;
}
+ else
+ {
+ user_defined_name = username + " " + lastname;
+ }
}
LLSD fav_llsd;
@@ -377,6 +455,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
}
break;
}
+ if (combo->getValue().asString().empty())
+ {
+ combo->selectFirstItem();
+ }
}
LLPanelLogin::~LLPanelLogin()
@@ -443,24 +525,6 @@ void LLPanelLogin::giveFocus()
}
// static
-void LLPanelLogin::showLoginWidgets()
-{
- if (sInstance)
- {
- // *NOTE: Mani - This may or may not be obselete code.
- // It seems to be part of the defunct? reg-in-client project.
- sInstance->getChildView("login_widgets")->setVisible( true);
- LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
-
- // *TODO: Append all the usual login parameters, like first_login=Y etc.
- std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
- web_browser->navigateTo( splash_screen_url, "text/html" );
- LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
- username_combo->setFocus(TRUE);
- }
-}
-
-// static
void LLPanelLogin::show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void* callback_data)
@@ -480,9 +544,64 @@ void LLPanelLogin::show(const LLRect &rect,
gFocusMgr.setDefaultKeyboardFocus(sInstance);
}
+//static
+void LLPanelLogin::reshapePanel()
+{
+ if (sInstance)
+ {
+ LLRect rect = sInstance->getRect();
+ sInstance->reshape(rect.getWidth(), rect.getHeight());
+ }
+}
+
+//static
+void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
+{
+ if (!sInstance)
+ {
+ 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);
+ }
+}
+
+//static
+void LLPanelLogin::resetFields()
+{
+ if (!sInstance)
+ {
+ // class not existing at this point might happen since this
+ // function is used to reset list in case of changes by external sources
+ return;
+ }
+ if (sInstance->mFirstLoginThisInstall)
+ {
+ // no list to populate
+ LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL;
+ }
+ else
+ {
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(cred);
+ }
+}
+
// static
-void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
- BOOL remember)
+void LLPanelLogin::setFields(LLPointer<LLCredential> credential)
{
if (!sInstance)
{
@@ -492,36 +611,43 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
sCredentialSet = TRUE;
LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
- LLSD identifier = credential->getIdentifier();
- if((std::string)identifier["type"] == "agent")
+ LLSD identifier = credential.notNull() ? credential->getIdentifier() : LLSD();
+
+ if(identifier.has("type") && (std::string)identifier["type"] == "agent")
{
+ // not nessesary for panel_login.xml, needed for panel_login_first.xml
std::string firstname = identifier["first_name"].asString();
std::string lastname = identifier["last_name"].asString();
std::string login_id = firstname;
- if (!lastname.empty() && lastname != "Resident")
+ if (!lastname.empty() && lastname != "Resident" && lastname != "resident")
{
// support traditional First Last name SLURLs
login_id += " ";
login_id += lastname;
}
- sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->mUsernameLength = login_id.length();
}
- else if((std::string)identifier["type"] == "account")
+ else if(identifier.has("type") && (std::string)identifier["type"] == "account")
{
- sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);
+ std::string login_id = identifier["account_name"].asString();
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->mUsernameLength = login_id.length();
}
else
{
- sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
+ sInstance->mUsernameLength = 0;
}
+
sInstance->addFavoritesToStartLocation();
// if the password exists in the credential, set the password field with
// a filler to get some stars
- LLSD authenticator = credential->getAuthenticator();
+ LLSD authenticator = credential.notNull() ? credential->getAuthenticator() : LLSD();
LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
if(authenticator.isMap() &&
authenticator.has("secret") &&
- (authenticator["secret"].asString().size() > 0) && remember)
+ (authenticator["secret"].asString().size() > 0))
{
// This is a MD5 hex digest of a password.
@@ -535,38 +661,28 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
}
else
{
- sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->mPasswordLength = 0;
}
- sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember);
}
-
// static
void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
- BOOL& remember)
+ bool& remember_user,
+ bool& remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted getFields with no login view shown" << LL_ENDL;
return;
}
-
- // load the credential so we can pass back the stored password or hash if the user did
- // not modify the password field.
-
- credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
LLSD identifier = LLSD::emptyMap();
LLSD authenticator = LLSD::emptyMap();
-
- if(credential.notNull())
- {
- authenticator = credential->getAuthenticator();
- }
- std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
- LLStringUtil::trim(username);
+ std::string username = sInstance->getChild<LLComboBox>("username_combo")->getSimple();
std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
+ LLStringUtil::trim(username);
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
@@ -581,11 +697,27 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
if (LLPanelLogin::sInstance->mPasswordModified)
{
- authenticator = LLSD::emptyMap();
// 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
{
@@ -597,7 +729,7 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
if (separator_index != username.npos)
{
last = username.substr(separator_index+1, username.npos);
- LLStringUtil::trim(last);
+ LLStringUtil::trim(last);
}
else
{
@@ -625,10 +757,29 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
pass.hex_digest(md5pass);
authenticator["secret"] = md5pass;
}
+ else
+ {
+ std::string key = first + "_" + last;
+ LLStringUtil::toLower(key);
+ credential = load_user_credentials(key);
+ if (credential.notNull())
+ {
+ authenticator = credential->getAuthenticator();
+ }
+ }
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
- remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
+ 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'
+ }
}
@@ -641,11 +792,8 @@ BOOL LLPanelLogin::areCredentialFieldsDirty()
}
else
{
- std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
- LLStringUtil::trim(username);
- std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
LLComboBox* combo = sInstance->getChild<LLComboBox>("username_combo");
- if(combo && combo->isDirty())
+ if (combo && combo->getCurrentIndex() == -1 && !combo->getValue().asString().empty())
{
return true;
}
@@ -816,9 +964,9 @@ void LLPanelLogin::loadLoginPage()
// Channel and Version
params["version"] = llformat("%s (%d)",
- LLVersionInfo::getShortVersion().c_str(),
- LLVersionInfo::getBuild());
- params["channel"] = LLVersionInfo::getChannel();
+ LLVersionInfo::instance().getShortVersion().c_str(),
+ LLVersionInfo::instance().getBuild());
+ params["channel"] = LLVersionInfo::instance().getChannel();
// Grid
params["grid"] = LLGridManager::getInstance()->getGridId();
@@ -898,8 +1046,8 @@ void LLPanelLogin::onClickConnect(void *)
{
sCredentialSet = FALSE;
LLPointer<LLCredential> cred;
- BOOL remember;
- getFields(cred, remember);
+ bool remember_1, remember_2;
+ getFields(cred, remember_1, remember_2);
std::string identifier_type;
cred->identifierType(identifier_type);
LLSD allowed_credential_types;
@@ -953,6 +1101,69 @@ void LLPanelLogin::onClickSignUp(void*)
}
// static
+void LLPanelLogin::onUserNameTextEnty(void*)
+{
+ sInstance->mPasswordModified = true;
+ sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->mPasswordLength = 0;
+ sInstance->addFavoritesToStartLocation(); //will call updateLoginButtons()
+}
+
+// static
+void LLPanelLogin::onUserListCommit(void*)
+{
+ if (sInstance)
+ {
+ LLComboBox* username_combo(sInstance->getChild<LLComboBox>("username_combo"));
+ static S32 ind = -1;
+ if (ind != username_combo->getCurrentIndex())
+ {
+ std::string user_key = username_combo->getSelectedValue();
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
+ setFields(cred);
+ sInstance->mPasswordModified = false;
+ }
+ else
+ {
+ std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
+ if (pass.empty())
+ {
+ sInstance->giveFocus();
+ }
+ else
+ {
+ onClickConnect(NULL);
+ }
+ }
+ }
+}
+
+// static
+// At the moment only happens if !mFirstLoginThisInstall
+void LLPanelLogin::onRememberUserCheck(void*)
+{
+ if (sInstance && !sInstance->mFirstLoginThisInstall)
+ {
+ 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)
+ {
+ remember = true;
+ remember_name->setValue(true);
+ LLNotificationsUtil::add("LoginCantRemoveUsername");
+ }
+ if (!remember)
+ {
+ remember_psswrd->setValue(false);
+ }
+ remember_psswrd->setEnabled(remember);
+ }
+}
+
+// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
LLPanelLogin *self = (LLPanelLogin *)user_data;
@@ -976,12 +1187,37 @@ void LLPanelLogin::updateServer()
try
{
// if they've selected another grid, we should load the credentials
- // for that grid and set them to the UI.
- if(!sInstance->areCredentialFieldsDirty())
+ // for that grid and set them to the UI. But if there were any modifications to
+ // fields, modifications should carry over.
+ // Not sure if it should carry over password but it worked like this before login changes
+ // Example: you started typing in and found that your are under wrong grid,
+ // you switch yet don't lose anything
+ if (sInstance->areCredentialFieldsDirty())
{
- LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
- bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
- sInstance->setFields(credential, remember);
+ // save modified creds
+ LLComboBox* user_combo = sInstance->getChild<LLComboBox>("username_combo");
+ LLLineEditor* pswd_edit = sInstance->getChild<LLLineEditor>("password_edit");
+ std::string username = user_combo->getSimple();
+ LLStringUtil::trim(username);
+ std::string password = pswd_edit->getValue().asString();
+
+ // populate dropbox and setFields
+ // Note: following call is related to initializeLoginInfo()
+ LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(credential);
+
+ // restore creds
+ user_combo->setTextEntry(username);
+ pswd_edit->setValue(password);
+ sInstance->mUsernameLength = username.length();
+ sInstance->mPasswordLength = password.length();
+ }
+ else
+ {
+ // populate dropbox and setFields
+ // Note: following call is related to initializeLoginInfo()
+ LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(credential);
}
// update the login panel links
@@ -1011,14 +1247,85 @@ void LLPanelLogin::updateLoginButtons()
LLButton* login_btn = getChild<LLButton>("connect_btn");
login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
+
+ if (!mFirstLoginThisInstall)
+ {
+ LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ if (user_combo->getCurrentIndex() != -1)
+ {
+ remember_name->setValue(true);
+ LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password");
+ remember_pass->setEnabled(TRUE);
+ } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user
+ }
+}
+
+void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential)
+{
+ LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
+ user_combo->removeall();
+ user_combo->clear();
+ user_combo->setValue(std::string());
+ getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ mUsernameLength = 0;
+ mPasswordLength = 0;
+
+ if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
+ {
+ LLSecAPIHandler::credential_map_t credencials;
+ gSecAPIHandler->loadCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), credencials);
+
+ LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
+ LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
+ while (cr_iter != cr_end)
+ {
+ if (cr_iter->second.notNull()) // basic safety in case of future changes
+ {
+ // cr_iter->first == user_id , to be able to be find it in case we select it
+ user_combo->add(LLPanelLogin::getUserName(cr_iter->second), cr_iter->first, ADD_BOTTOM, TRUE);
+ }
+ cr_iter++;
+ }
+
+ if (credential.isNull() || !user_combo->setSelectedByValue(LLSD(credential->userID()), true))
+ {
+ // selection failed, fields will be mepty
+ updateLoginButtons();
+ }
+ else
+ {
+ setFields(credential);
+ }
+ }
+ else
+ {
+ if (credential.notNull())
+ {
+ const LLSD &ident = credential->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ // this llsd might hold invalid credencial (failed login), so
+ // do not add to the list, just set field.
+ setFields(credential);
+ }
+ else
+ {
+ updateLoginButtons();
+ }
+ }
+ else
+ {
+ updateLoginButtons();
+ }
+ }
}
+
void LLPanelLogin::onSelectServer()
{
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
- LLPointer<LLCredential> credential;
-
LLComboBox* server_combo = getChild<LLComboBox>("server_combo");
LLSD server_combo_val = server_combo->getSelectedValue();
LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL;
@@ -1040,21 +1347,23 @@ void LLPanelLogin::onSelectServer()
switch (index)
{
case 0: // last location
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
+ break;
case 1: // home location
- // do nothing - these are grid-agnostic locations
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
break;
default:
{
std::string location = location_combo->getValue().asString();
LLSLURL slurl(location); // generata a slurl from the location combo contents
- if ( slurl.getType() == LLSLURL::LOCATION
- && slurl.getGrid() != LLGridManager::getInstance()->getGrid()
- )
+ if (location.empty()
+ || (slurl.getType() == LLSLURL::LOCATION
+ && slurl.getGrid() != LLGridManager::getInstance()->getGrid())
+ )
{
// the grid specified by the location is not this one, so clear the combo
location_combo->setCurrentByIndex(0); // last location on the new grid
- location_combo->setTextEntry(LLStringUtil::null);
}
}
break;
@@ -1077,3 +1386,34 @@ bool LLPanelLogin::getShowFavorites()
{
return gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
}
+
+// static
+std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
+{
+ if (cred.isNull())
+ {
+ return "unknown";
+ }
+ const LLSD &ident = cred->getIdentifier();
+
+ if (!ident.isMap())
+ {
+ return "unknown";
+ }
+ else if ((std::string)ident["type"] == "agent")
+ {
+ std::string second_name = ident["last_name"];
+ if (second_name == "resident" || second_name == "Resident")
+ {
+ return (std::string)ident["first_name"];
+ }
+ return (std::string)ident["first_name"] + " " + (std::string)ident["last_name"];
+ }
+ else if ((std::string)ident["type"] == "account")
+ {
+ return LLCacheName::cleanFullName((std::string)ident["account_name"]);
+ }
+
+ return "unknown";
+}
+
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c633582d89..788c269ffd 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -54,10 +54,11 @@ public:
static void show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void* callback_data);
+ static void reshapePanel();
- static void setFields(LLPointer<LLCredential> credential, BOOL remember);
-
- static void getFields(LLPointer<LLCredential>& credential, BOOL& remember);
+ static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
+ static void resetFields();
+ static void getFields(LLPointer<LLCredential>& credential, bool& remember_user, bool& remember_psswrd);
static BOOL isCredentialSet() { return sCredentialSet; }
@@ -72,8 +73,6 @@ public:
void setSiteIsAlive( bool alive );
- void showLoginWidgets();
-
static void loadLoginPage();
static void giveFocus();
static void setAlwaysRefresh(bool refresh);
@@ -88,6 +87,9 @@ public:
// called from prefs when initializing panel
static bool getShowFavorites();
+ // extract name from cred in a format apropriate for username field
+ static std::string getUserName(LLPointer<LLCredential> &cred);
+
private:
friend class LLPanelLoginListener;
void addFavoritesToStartLocation();
@@ -95,11 +97,16 @@ private:
void onSelectServer();
void onLocationSLURL();
+ static void setFields(LLPointer<LLCredential> credential);
+
static void onClickConnect(void*);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickSignUp(void*);
+ static void onUserNameTextEnty(void*);
+ static void onUserListCommit(void*);
+ static void onRememberUserCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
@@ -107,6 +114,7 @@ private:
boost::scoped_ptr<LLPanelLoginListener> mListener;
void updateLoginButtons();
+ void populateUserList(LLPointer<LLCredential> credential);
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index f63e604927..e9c9c451a2 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -28,12 +28,12 @@
#include "llpanelmaininventory.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llavataractions.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldndbutton.h"
-#include "lleconomy.h"
#include "llfilepicker.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@@ -58,6 +58,7 @@
#include "llsidepanelinventory.h"
#include "llfolderview.h"
#include "llradiogroup.h"
+#include "llenvironment.h"
const std::string FILTERS_FILENAME("filters.xml");
@@ -114,6 +115,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mSavedFolderState(NULL),
mFilterText(""),
mMenuGearDefault(NULL),
+ mMenuVisibility(NULL),
mMenuAddHandle(),
mNeedUploadCost(true)
{
@@ -128,6 +130,9 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
+ mEnableCallbackRegistrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasSettingsInventory(); });
+
+
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
}
@@ -161,6 +166,7 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ recent_items_panel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems");
@@ -214,6 +220,17 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
}
}
+ if(mActivePanel)
+ {
+ if(savedFilterState.has(mActivePanel->getFilter().getName()))
+ {
+ LLSD items = savedFilterState.get(mActivePanel->getFilter().getName());
+ LLInventoryFilter::Params p;
+ LLParamSDParser parser;
+ parser.readSD(items, p);
+ mActivePanel->getFilter().setSearchVisibilityTypes(p);
+ }
+ }
}
@@ -224,19 +241,20 @@ BOOL LLPanelMainInventory::postBuild()
}
mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
+ mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
initListCommandsHandlers();
- // *TODO:Get the cost info from the server
- const std::string upload_cost("10");
+ const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
- menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
- menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
- menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
- menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
+ menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
+ menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
+ menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
}
// Trigger callback for focus received so we can deselect items in inbox/outbox
@@ -249,6 +267,9 @@ BOOL LLPanelMainInventory::postBuild()
LLPanelMainInventory::~LLPanelMainInventory( void )
{
// Save the filters state.
+ // Some params types cannot be saved this way
+ // for example, LLParamSDParser doesn't know about U64,
+ // so some FilterOps params should be revised.
LLSD filterRoot;
LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
if (all_items_panel)
@@ -904,6 +925,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_sound")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND));
getChild<LLUICtrl>("check_texture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE));
getChild<LLUICtrl>("check_snapshot")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT));
+ getChild<LLUICtrl>("check_settings")->setValue((S32)(filter_types & 0x1 << LLInventoryType::IT_SETTINGS));
getChild<LLUICtrl>("check_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS);
getChild<LLUICtrl>("check_created_by_me")->setValue(show_created_by_me);
@@ -990,6 +1012,12 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
+ if (!getChild<LLUICtrl>("check_settings")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_SETTINGS);
+ filtered_by_all_types = FALSE;
+ }
+
if (!filtered_by_all_types || (mPanelMainInventory->getPanel()->getFilter().getFilterTypes() & LLInventoryFilter::FILTERTYPE_DATE))
{
// don't include folders in filter, unless I've selected everything or filtering by date
@@ -1107,6 +1135,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_sound")->setValue(TRUE);
self->getChild<LLUICtrl>("check_texture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_settings")->setValue(TRUE);
}
//static
@@ -1126,6 +1155,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_sound")->setValue(FALSE);
self->getChild<LLUICtrl>("check_texture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_snapshot")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_settings")->setValue(FALSE);
}
//////////////////////////////////////////////////////////////////////////////////
@@ -1151,6 +1181,10 @@ void LLPanelMainInventory::initListCommandsHandlers()
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAddHandle = menu->getHandle();
+ mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mVisibilityMenuButton->setMenu(mMenuVisibility);
+ mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT);
+
// Update the trash button when selected item(s) get worn or taken off.
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
}
@@ -1340,6 +1374,21 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
}
LLFloaterReg::showInstance("linkreplace", params);
}
+
+ if (command_name == "toggle_search_trash")
+ {
+ mActivePanel->getFilter().toggleSearchVisibilityTrash();
+ }
+
+ if (command_name == "toggle_search_library")
+ {
+ mActivePanel->getFilter().toggleSearchVisibilityLibrary();
+ }
+
+ if (command_name == "include_links")
+ {
+ mActivePanel->getFilter().toggleSearchVisibilityLinks();
+ }
}
void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
@@ -1485,6 +1534,21 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
}
+ if (command_name == "toggle_search_trash")
+ {
+ return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0;
+ }
+
+ if (command_name == "toggle_search_library")
+ {
+ return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0;
+ }
+
+ if (command_name == "include_links")
+ {
+ return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;
+ }
+
return FALSE;
}
@@ -1504,38 +1568,23 @@ bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType
void LLPanelMainInventory::setUploadCostIfNeeded()
{
- // *NOTE dzaporozhan
- // Upload cost is set in process_economy_data() (llviewermessage.cpp). But since we
- // have two instances of Inventory panel at the moment(and two instances of context menu),
- // call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances.
-
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if(mNeedUploadCost && menu)
{
- LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload");
- if(upload_menu)
- {
- S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
- std::string cost_str;
-
- // getPriceUpload() returns -1 if no data available yet.
- if(upload_cost >= 0)
- {
- mNeedUploadCost = false;
- cost_str = llformat("%d", upload_cost);
- }
- else
- {
- cost_str = llformat("%d", gSavedSettings.getU32("DefaultUploadCost"));
- }
+ const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
- upload_menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", cost_str);
- upload_menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", cost_str);
- upload_menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", cost_str);
- upload_menu->getChild<LLView>("Bulk Upload")->setLabelArg("[COST]", cost_str);
- }
+ menu->getChild<LLView>("Upload Image")->setLabelArg("[COST]", texture_upload_cost_str);
+ menu->getChild<LLView>("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str);
+ menu->getChild<LLView>("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str);
}
}
+bool LLPanelMainInventory::hasSettingsInventory()
+{
+ return LLEnvironment::instance().isInventoryEnabled();
+}
+
// List Commands //
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 732a3b04e3..dfb8db9d12 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -93,6 +93,8 @@ public:
void toggleFindOptions();
+ void resetFilters();
+
protected:
//
// Misc functions
@@ -117,7 +119,6 @@ protected:
void doToSelected(const LLSD& userdata);
void closeAllFolders();
void doCreate(const LLSD& userdata);
- void resetFilters();
void setSortBy(const LLSD& userdata);
void saveTexture(const LLSD& userdata);
bool isSaveTextureEnabled(const LLSD& userdata);
@@ -161,6 +162,7 @@ protected:
BOOL isActionChecked(const LLSD& userdata);
void onCustomAction(const LLSD& command_name);
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
+ static bool hasSettingsInventory();
/**
* Set upload cost in "Upload" sub menu.
*/
@@ -168,7 +170,9 @@ protected:
private:
LLDragAndDropButton* mTrashButton;
LLToggleableMenu* mMenuGearDefault;
+ LLToggleableMenu* mMenuVisibility;
LLMenuButton* mGearMenuButton;
+ LLMenuButton* mVisibilityMenuButton;
LLHandle<LLView> mMenuAddHandle;
bool mNeedUploadCost;
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index cea7054d6a..7a6631448b 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -36,12 +36,15 @@
#include "llpanellandmarks.h"
#include "llplacesinventorybridge.h"
#include "llviewerfoldertype.h"
+#include "llsdserialize.h"
#define DEBUGGING_FRESHNESS 0
const LLColor4U DEFAULT_WHITE(255, 255, 255);
+const std::string NEW_INBOX_FILENAME("inbox_new_items.xml");
+
//
// statics
//
@@ -57,7 +60,9 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_
LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
: LLInventoryPanel(p)
-{}
+{
+ LLInboxNewItemsStorage::getInstance()->load();
+}
LLInboxInventoryPanel::~LLInboxInventoryPanel()
{}
@@ -127,7 +132,7 @@ void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
}
// Compute freshness if our parent is the root folder for the inbox
- if (mParentFolder == mRoot)
+ if ((mParentFolder == mRoot) && !mFresh)
{
computeFreshness();
}
@@ -145,6 +150,12 @@ void LLInboxFolderViewFolder::draw()
setBadgeVisibility(mFresh);
LLFolderViewFolder::draw();
+
+ if (mFresh)
+ {
+ reshapeBadge(getRect());
+ }
+
}
BOOL LLInboxFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
@@ -167,11 +178,12 @@ void LLInboxFolderViewFolder::selectItem()
void LLInboxFolderViewFolder::computeFreshness()
{
+ LLFolderViewModelItemInventory* view_model = static_cast<LLFolderViewModelItemInventory*>(getViewModelItem());
const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity");
if (last_expansion_utc > 0)
{
- mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
+ mFresh = (view_model->getCreationDate() > last_expansion_utc) || LLInboxNewItemsStorage::getInstance()->isItemFresh(view_model->getUUID());
#if DEBUGGING_FRESHNESS
if (mFresh)
@@ -184,6 +196,11 @@ void LLInboxFolderViewFolder::computeFreshness()
{
mFresh = true;
}
+
+ if (mFresh)
+ {
+ LLInboxNewItemsStorage::getInstance()->addFreshItem(view_model->getUUID());
+ }
}
void LLInboxFolderViewFolder::deFreshify()
@@ -191,6 +208,7 @@ void LLInboxFolderViewFolder::deFreshify()
mFresh = false;
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+ LLInboxNewItemsStorage::getInstance()->removeItem(static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getUUID());
}
//
@@ -271,5 +289,55 @@ void LLInboxFolderViewItem::deFreshify()
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
+LLInboxNewItemsStorage::LLInboxNewItemsStorage()
+{
+}
+
+// static
+void LLInboxNewItemsStorage::destroyClass()
+{
+ LLInboxNewItemsStorage::getInstance()->saveNewItemsIds();
+}
+
+void LLInboxNewItemsStorage::saveNewItemsIds()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME);
+ if (!filename.empty())
+ {
+ LLSD uuids_data;
+ for (std::set<LLUUID>::const_iterator it = mNewItemsIDs.begin(); it != mNewItemsIDs.end(); it++)
+ {
+ uuids_data.append((*it));
+ }
+ llofstream file;
+ file.open(filename.c_str());
+ if ( file.is_open() )
+ {
+ LLSDSerialize::toPrettyXML(uuids_data, file);
+ file.close();
+ }
+ }
+}
+
+void LLInboxNewItemsStorage::load()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME);
+ if (!filename.empty())
+ {
+ llifstream in_file;
+ in_file.open(filename.c_str());
+
+ LLSD uuids_data;
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(uuids_data, in_file);
+ in_file.close();
+ for (LLSD::array_iterator i = uuids_data.beginArray(); i != uuids_data.endArray(); ++i)
+ {
+ mNewItemsIDs.insert((*i).asUUID());
+ }
+ }
+ }
+}
// eof
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 0b27818c95..3e508e801b 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -113,4 +113,23 @@ protected:
bool mFresh;
};
+class LLInboxNewItemsStorage : public LLSingleton<LLInboxNewItemsStorage>
+ , public LLDestroyClass<LLInboxNewItemsStorage>
+{
+ LLSINGLETON(LLInboxNewItemsStorage);
+ LOG_CLASS(LLInboxNewItemsStorage);
+public:
+ static void destroyClass();
+ void saveNewItemsIds();
+
+ void load();
+
+ void addFreshItem(const LLUUID& id) { mNewItemsIDs.insert(id); }
+ void removeItem(const LLUUID& id) { mNewItemsIDs.erase(id); }
+ bool isItemFresh(const LLUUID& id) { return (mNewItemsIDs.find(id) != mNewItemsIDs.end()); }
+
+private:
+ std::set<LLUUID> mNewItemsIDs;
+};
+
#endif //LL_INBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 2dca55514d..02911313ed 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -43,6 +43,7 @@
#include "llbutton.h"
#include "lltextbox.h"
#include "llviewermedia.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerregion.h"
#include "llviewermediafocus.h"
@@ -65,9 +66,6 @@ extern LLControlGroup gSavedSettings;
static const LLUUID PARCEL_MEDIA_LIST_ITEM_UUID = LLUUID("CAB5920F-E484-4233-8621-384CF373A321");
static const LLUUID PARCEL_AUDIO_LIST_ITEM_UUID = LLUUID("DF4B020D-8A24-4B95-AB5D-CA970D694822");
-const F32 AUTO_CLOSE_FADE_TIME_START= 2.0f;
-const F32 AUTO_CLOSE_FADE_TIME_END = 3.0f;
-
//
// LLPanelNearByMedia
//
@@ -81,12 +79,11 @@ LLPanelNearByMedia::LLPanelNearByMedia()
mParcelMediaItem(NULL),
mParcelAudioItem(NULL)
{
- mHoverTimer.stop();
-
- mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+ // This is just an initial value, mParcelAudioAutoStart does not affect ParcelMediaAutoPlayEnable
+ mParcelAudioAutoStart = gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0
+ && gSavedSettings.getBOOL("MediaTentativeAutoPlay");
- gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
+ gSavedSettings.getControl("ParcelMediaAutoPlayEnable")->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll", boost::bind(&LLPanelNearByMedia::onClickEnableAll, this));
mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll", boost::bind(&LLPanelNearByMedia::onClickDisableAll, this));
@@ -109,7 +106,7 @@ LLPanelNearByMedia::~LLPanelNearByMedia()
BOOL LLPanelNearByMedia::postBuild()
{
- LLPanel::postBuild();
+ LLPanelPulldown::postBuild();
const S32 RESIZE_BAR_THICKNESS = 6;
LLResizeBar::Params p;
@@ -177,50 +174,24 @@ BOOL LLPanelNearByMedia::postBuild()
void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
{
- // update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
- mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay");
-}
-
-/*virtual*/
-void LLPanelNearByMedia::onMouseEnter(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.stop();
- LLPanel::onMouseEnter(x,y,mask);
-}
-
-
-/*virtual*/
-void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.start();
- LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelNearByMedia::onTopLost()
-{
- setVisible(FALSE);
-}
-
-
-/*virtual*/
-void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility )
-{
- if (new_visibility)
- {
- mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
- }
- else
- {
- mHoverTimer.stop();
- }
+ // update mParcelAudioAutoStartMode if "ParcelMediaAutoPlayEnable" changes
+ S32 value = gSavedSettings.getS32("ParcelMediaAutoPlayEnable");
+ mParcelAudioAutoStart = value != 0
+ && gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+
+ LLViewerParcelAskPlay *inst = LLViewerParcelAskPlay::getInstance();
+ if (value == 2 && !inst->hasData())
+ {
+ // Init if nessesary
+ inst->loadSettings();
+ }
+ inst->cancelNotification();
}
/*virtual*/
void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
{
- LLPanel::reshape(width, height, called_from_parent);
+ LLPanelPulldown::reshape(width, height, called_from_parent);
LLButton* more_btn = findChild<LLButton>("more_btn");
if (more_btn && more_btn->getValue().asBoolean())
@@ -244,24 +215,14 @@ void LLPanelNearByMedia::draw()
refreshList();
updateControls();
-
- F32 alpha = mHoverTimer.getStarted()
- ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START, AUTO_CLOSE_FADE_TIME_END, 1.f, 0.f)
- : 1.0f;
- LLViewDrawContext context(alpha);
- LLPanel::draw();
-
- if (alpha == 0.f)
- {
- setVisible(false);
- }
+ LLPanelPulldown::draw();
}
/*virtual*/
BOOL LLPanelNearByMedia::handleHover(S32 x, S32 y, MASK mask)
{
- LLPanel::handleHover(x, y, mask);
+ LLPanelPulldown::handleHover(x, y, mask);
// If we are hovering over this panel, make sure to clear any hovered media
// ID. Note that the more general solution would be to clear this ID when
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index a9c1b190cf..2d898d0aa1 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -27,7 +27,7 @@
#ifndef LL_LLPANELNEARBYMEDIA_H
#define LL_LLPANELNEARBYMEDIA_H
-#include "llpanel.h"
+#include "llpanelpulldown.h"
class LLPanelNearbyMedia;
class LLButton;
@@ -39,16 +39,12 @@ class LLTextBox;
class LLComboBox;
class LLViewerMediaImpl;
-class LLPanelNearByMedia : public LLPanel
+class LLPanelNearByMedia : public LLPanelPulldown
{
public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
- /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ void onTopLost();
- /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
@@ -173,7 +169,6 @@ private:
LLRect mMoreRect;
LLRect mLessRect;
- LLFrameTimer mHoverTimer;
LLScrollListItem* mParcelMediaItem;
LLScrollListItem* mParcelAudioItem;
};
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 3665910c63..6bff95ab36 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -30,7 +30,6 @@
#include "llpanelobject.h"
// linden library includes
-#include "lleconomy.h"
#include "llerror.h"
#include "llfontgl.h"
#include "llpermissionsflags.h"
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 6702dae4d6..ecadc9443b 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -143,6 +143,7 @@ public:
virtual bool hasChildren() const { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual LLSettingsType::type_e getSettingsType() const { return LLSettingsType::ST_NONE; }
virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
@@ -702,6 +703,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_CALLINGCARD:
case DAD_MESH:
+ case DAD_SETTINGS:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{
@@ -1122,6 +1124,33 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const
}
///----------------------------------------------------------------------------
+/// Class LLTaskSettingsBridge
+///----------------------------------------------------------------------------
+
+class LLTaskSettingsBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskSettingsBridge(LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name,
+ U32 flags) :
+ LLTaskInvFVBridge(panel, uuid, name, flags) {}
+
+ virtual LLUIImagePtr getIcon() const;
+ virtual LLSettingsType::type_e getSettingsType() const;
+};
+
+LLUIImagePtr LLTaskSettingsBridge::getIcon() const
+{
+ return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE);
+}
+
+LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
+{
+ return LLSettingsType::ST_NONE;
+}
+
+///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1202,6 +1231,12 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_id,
object_name);
break;
+ case LLAssetType::AT_SETTINGS:
+ new_bridge = new LLTaskSettingsBridge(panel,
+ object_id,
+ object_name,
+ itemflags);
+ break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
@@ -1561,12 +1596,13 @@ void LLPanelObjectInventory::refresh()
//LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL;
BOOL has_inventory = FALSE;
const BOOL non_root_ok = TRUE;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
- if(node)
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok);
+ if(node && node->mValid)
{
LLViewerObject* object = node->getObject();
- if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
- || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
+ if(object && ((selection->getRootObjectCount() == 1)
+ || (selection->getObjectCount() == 1)))
{
// determine if we need to make a request. Start with a
// default based on if we have inventory at all.
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 1d87aa6f5d..5be9ab6095 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -58,7 +58,6 @@
#include "llmenubutton.h"
#include "llpaneloutfitsinventory.h"
#include "lluiconstants.h"
-#include "llsaveoutfitcombobtn.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "lltoggleablemenu.h"
@@ -80,6 +79,8 @@ const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LL
const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
static const std::string REVERT_BTN("revert_btn");
+static const std::string SAVE_AS_BTN("save_as_btn");
+static const std::string SAVE_BTN("save_btn");
///////////////////////////////////////////////////////////////////////////////
@@ -562,7 +563,10 @@ BOOL LLPanelOutfitEdit::postBuild()
mGearMenu = LLPanelOutfitEditGearMenu::create();
mGearMenuBtn->setMenu(mGearMenu);
- mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
+ getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false));
+ getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
+
+ onOutfitChanging(gAgentWearables.isCOFChangeInProgress());
return TRUE;
}
@@ -703,6 +707,10 @@ void LLPanelOutfitEdit::onListViewFilterCommitted(LLUICtrl* ctrl)
S32 curr_filter_type = mListViewFilterCmbBox->getCurrentIndex();
if (curr_filter_type < 0) return;
+ if (curr_filter_type >= LVIT_SHAPE)
+ {
+ mWearableItemsList->setMenuWearableType(LLWearableType::EType(curr_filter_type - LVIT_SHAPE));
+ }
mWearableListManager->setFilterCollector(mListViewItemTypes[curr_filter_type]->collector);
}
@@ -1233,11 +1241,9 @@ void LLPanelOutfitEdit::updateVerbs()
bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();
bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull();
- mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty);
+ getChildView(SAVE_BTN)->setEnabled(!outfit_locked && outfit_is_dirty);
getChildView(REVERT_BTN)->setEnabled(outfit_is_dirty && has_baseoutfit);
- mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty);
-
mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing"));
updateCurrentOutfitName();
@@ -1282,6 +1288,7 @@ void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type
//e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE
applyListViewFilter(static_cast<EListViewItemType>(LVIT_SHAPE + type));
+ mWearableItemsList->setMenuWearableType(type);
}
static void update_status_widget_rect(LLView * widget, S32 right_border)
@@ -1422,4 +1429,13 @@ void LLPanelOutfitEdit::saveListSelection()
}
}
+void LLPanelOutfitEdit::saveOutfit(bool as_new)
+{
+ LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance();
+ if (panel_outfits_inventory)
+ {
+ panel_outfits_inventory->saveOutfit(as_new);
+ }
+}
+
// EOF
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 3c6efac0e7..d0597fb72b 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -58,7 +58,6 @@ class LLMenuButton;
class LLMenuGL;
class LLFindNonLinksByMask;
class LLFindWearablesOfType;
-class LLSaveOutfitComboBtn;
class LLWearableItemTypeNameComparator;
class LLPanelOutfitEdit : public LLPanel
@@ -195,6 +194,7 @@ private:
void getSelectedItemsUUID(uuid_vec_t& uuid_list);
void getCurrentItemUUID(LLUUID& selected_id);
void onCOFChanged();
+ void saveOutfit(bool as_new = false);
/**
* Method preserves selection while switching between folder/list view modes
@@ -237,7 +237,6 @@ private:
LLToggleableMenu* mGearMenu;
LLToggleableMenu* mAddWearablesGearMenu;
bool mInitialized;
- std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
LLMenuButton* mWearablesGearMenuBtn;
LLMenuButton* mGearMenuBtn;
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 8019335f97..531073526b 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -40,7 +40,6 @@
#include "lloutfitgallery.h"
#include "lloutfitslist.h"
#include "llpanelwearing.h"
-#include "llsaveoutfitcombobtn.h"
#include "llsidepanelappearance.h"
#include "llviewercontrol.h"
#include "llviewerfoldertype.h"
@@ -49,12 +48,16 @@ static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";
static const std::string COF_TAB_NAME = "cof_tab";
+static const std::string SAVE_AS_BTN("save_as_btn");
+static const std::string SAVE_BTN("save_btn");
+
static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mMyOutfitsPanel(NULL),
mCurrentOutfitPanel(NULL),
mActivePanel(NULL),
+ mAppearanceTabs(NULL),
mInitialized(false)
{
gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
@@ -89,8 +92,9 @@ BOOL LLPanelOutfitsInventory::postBuild()
{
LLInventoryModelBackgroundFetch::instance().start(outfits_cat);
}
-
- mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true));
+
+ getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false));
+ getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true));
return TRUE;
}
@@ -245,6 +249,12 @@ LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance()
return dynamic_cast<LLPanelOutfitsInventory*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfits_inventory"));
}
+void LLPanelOutfitsInventory::openApearanceTab(const std::string& tab_name)
+{
+ if (!mAppearanceTabs) return;
+ mAppearanceTabs->selectTabByName(tab_name);
+}
+
//////////////////////////////////////////////////////////////////////////////////
// List Commands //
@@ -268,7 +278,7 @@ void LLPanelOutfitsInventory::updateListCommands()
mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled);
wear_btn->setEnabled(wear_enabled);
wear_btn->setVisible(wear_visible);
- mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
+ getChild<LLButton>(SAVE_BTN)->setEnabled(make_outfit_enabled);
wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip"));
}
@@ -312,6 +322,7 @@ void LLPanelOutfitsInventory::initTabPanels()
void LLPanelOutfitsInventory::onTabChange()
{
+ if (!mAppearanceTabs) return;
mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
if (!mActivePanel) return;
@@ -366,3 +377,15 @@ LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()
dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
return panel_appearance;
}
+
+void LLPanelOutfitsInventory::saveOutfit(bool as_new)
+{
+ if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
+ {
+ // we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved.
+ // If updateBaseOutfit fails, ask for an outfit name anyways
+ return;
+ }
+
+ onSave();
+}
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 6a0ea04fa6..50d7074d4b 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -38,7 +38,6 @@ class LLPanelWearing;
class LLMenuGL;
class LLSidepanelAppearance;
class LLTabContainer;
-class LLSaveOutfitComboBtn;
class LLPanelOutfitsInventory : public LLPanel
{
@@ -52,6 +51,7 @@ public:
void onSearchEdit(const std::string& string);
void onSave();
+ void saveOutfit(bool as_new = false);
bool onSaveCommit(const LLSD& notification, const LLSD& response);
@@ -59,13 +59,14 @@ public:
static LLPanelOutfitsInventory* findInstance();
+ void openApearanceTab(const std::string& tab_name);
+
protected:
void updateVerbs();
private:
LLTabContainer* mAppearanceTabs;
std::string mFilterSubString;
- std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
//////////////////////////////////////////////////////////////////////////////////
// tab panels //
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index be174475e1..5997d522c4 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -47,6 +47,7 @@
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llavataractions.h"
#include "llavatarlist.h"
#include "llavatarlistitem.h"
@@ -85,11 +86,6 @@ static const std::string RECENT_TAB_NAME = "recent_panel";
static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars
static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
-const S32 BASE_MAX_AGENT_GROUPS = 42;
-const S32 PREMIUM_MAX_AGENT_GROUPS = 60;
-
-extern S32 gMaxAgentGroups;
-
/** Comparator for comparing avatar items by last interaction date */
class LLAvatarItemRecentComparator : public LLAvatarItemComparator
{
@@ -612,26 +608,17 @@ void LLPanelPeople::removePicker()
BOOL LLPanelPeople::postBuild()
{
- S32 max_premium = PREMIUM_MAX_AGENT_GROUPS;
- if (gAgent.getRegion())
- {
- LLSD features;
- gAgent.getRegion()->getSimulatorFeatures(features);
- if (features.has("MaxAgentGroupsPremium"))
- {
- max_premium = features["MaxAgentGroupsPremium"].asInteger();
- }
- }
+ S32 max_premium = LLAgentBenefitsMgr::get("Premium").getGroupMembershipLimit();
getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
- if(gMaxAgentGroups < max_premium)
+ if(LLAgentBenefitsMgr::current().getGroupMembershipLimit() < max_premium)
{
- getChild<LLTextBox>("groupcount")->setText(getString("GroupCountWithInfo"));
- getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));
+ getChild<LLTextBox>("groupcount")->setText(getString("GroupCountWithInfo"));
+ getChild<LLTextBox>("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this));
}
mTabContainer = getChild<LLTabContainer>("tabs");
@@ -674,6 +661,7 @@ BOOL LLPanelPeople::postBuild()
mRecentList->setShowIcons("RecentListShowIcons");
mGroupList = getChild<LLGroupList>("group_list");
+ mGroupList->setNoItemsCommentText(getString("no_groups_msg"));
mGroupList->setNoItemsMsg(getString("no_groups_msg"));
mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
@@ -876,9 +864,10 @@ void LLPanelPeople::updateButtons()
groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
U32 groups_count = gAgent.mGroups.size();
- U32 groups_ramaining = gMaxAgentGroups > groups_count ? gMaxAgentGroups - groups_count : 0;
+ S32 max_groups = LLAgentBenefitsMgr::current().getGroupMembershipLimit();
+ U32 groups_remaining = max_groups > groups_count ? max_groups - groups_count : 0;
groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d", groups_count));
- groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_ramaining));
+ groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d", groups_remaining));
}
else
{
@@ -1095,25 +1084,22 @@ void LLPanelPeople::onGroupLimitInfo()
{
LLSD args;
- S32 max_basic = BASE_MAX_AGENT_GROUPS;
- S32 max_premium = PREMIUM_MAX_AGENT_GROUPS;
- if (gAgent.getRegion())
+ S32 max_basic = LLAgentBenefitsMgr::get("Base").getGroupMembershipLimit();
+ S32 max_premium = LLAgentBenefitsMgr::get("Premium").getGroupMembershipLimit();
+
+ args["MAX_BASIC"] = max_basic;
+ args["MAX_PREMIUM"] = max_premium;
+
+ if (LLAgentBenefitsMgr::has("Premium Plus"))
{
- LLSD features;
- gAgent.getRegion()->getSimulatorFeatures(features);
- if (features.has("MaxAgentGroupsBasic"))
- {
- max_basic = features["MaxAgentGroupsBasic"].asInteger();
- }
- if (features.has("MaxAgentGroupsPremium"))
- {
- max_premium = features["MaxAgentGroupsPremium"].asInteger();
- }
+ S32 max_premium_plus = LLAgentBenefitsMgr::get("Premium Plus").getGroupMembershipLimit();
+ args["MAX_PREMIUM_PLUS"] = max_premium_plus;
+ LLNotificationsUtil::add("GroupLimitInfoPlus", args);
}
- args["MAX_BASIC"] = max_basic;
- args["MAX_PREMIUM"] = max_premium;
-
- LLNotificationsUtil::add("GroupLimitInfo", args);
+ else
+ {
+ LLNotificationsUtil::add("GroupLimitInfo", args);
+ }
}
void LLPanelPeople::onTabSelected(const LLSD& param)
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index ef16427713..3e770958da 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -972,13 +972,45 @@ void LLPanelPermissions::refresh()
getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
}
+// Shorten name if it doesn't fit into max_pixels of two lines
+void shorten_name(std::string &name, const LLStyle::Params& style_params, S32 max_pixels)
+{
+ const LLFontGL* font = style_params.font();
+
+ LLWString wline = utf8str_to_wstring(name);
+ // panel supports two lines long names
+ S32 segment_length = font->maxDrawableChars(wline.c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
+ if (segment_length == wline.length())
+ {
+ // no work needed
+ return;
+ }
+
+ S32 first_line_length = segment_length;
+ segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels, wline.length(), LLFontGL::ANYWHERE);
+ if (segment_length + first_line_length == wline.length())
+ {
+ // no work needed
+ return;
+ }
+
+ // name does not fit, cut it, add ...
+ const LLWString dots_pad(utf8str_to_wstring(std::string("....")));
+ S32 elipses_width = font->getWidthF32(dots_pad.c_str());
+ segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE);
+
+ name = name.substr(0, segment_length + first_line_length) + std::string("...");
+}
+
void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params)
{
if (mOwnerCacheConnection.connected())
{
mOwnerCacheConnection.disconnect();
}
- mLabelOwnerName->setText(owner_name.getCompleteName(), style_params);
+ std::string name = owner_name.getCompleteName();
+ shorten_name(name, style_params, mLabelOwnerName->getLocalRect().getWidth());
+ mLabelOwnerName->setText(name, style_params);
}
void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params)
@@ -987,7 +1019,9 @@ void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAva
{
mCreatorCacheConnection.disconnect();
}
- mLabelCreatorName->setText(creator_name.getCompleteName(), style_params);
+ std::string name = creator_name.getCompleteName();
+ shorten_name(name, style_params, mLabelCreatorName->getLocalRect().getWidth());
+ mLabelCreatorName->setText(name, style_params);
}
// static
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index c39df3fe8b..4762e15d8f 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -37,6 +37,7 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llnotificationsutil.h"
+#include "llstartup.h"
#include "lltexturectrl.h"
#include "lltoggleablemenu.h"
#include "lltrans.h"
@@ -84,6 +85,11 @@ public:
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"));
@@ -198,6 +204,11 @@ public:
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"));
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 0c70aa87c2..9157df789f 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -43,6 +43,7 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
#include "llpanelpick.h"
+#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
#include "llhttpconstants.h"
@@ -78,6 +79,7 @@ BOOL LLPanelPlaceInfo::postBuild()
mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
mRegionName = getChild<LLTextBox>("region_title");
mParcelName = getChild<LLTextBox>("parcel_title");
+ mParcelOwner = getChild<LLTextBox>("parcel_owner");
mDescEditor = getChild<LLExpandableTextBox>("description");
mMaturityRatingIcon = getChild<LLIconCtrl>("maturity_icon");
@@ -98,11 +100,13 @@ void LLPanelPlaceInfo::resetLocation()
mParcelID.setNull();
mRequestedID.setNull();
mPosRegion.clearVec();
+ mRegionTitle.clear();
std::string loading = LLTrans::getString("LoadingData");
mMaturityRatingText->setValue(loading);
- mRegionName->setText(loading);
+ mRegionName->setTextArg("[REGIONAMEPOS]", loading);
mParcelName->setText(loading);
+ mParcelOwner->setText(loading);
mDescEditor->setText(loading);
mMaturityRatingIcon->setValue(LLUUID::null);
@@ -182,9 +186,11 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
std::string not_available = getString("not_available");
mMaturityRatingText->setValue(not_available);
- mRegionName->setText(not_available);
+ mRegionName->setTextArg("[REGIONAMEPOS]", not_available);
mParcelName->setText(not_available);
+ mParcelOwner->setText(not_available);
mMaturityRatingIcon->setValue(LLUUID::null);
+ mRegionTitle.clear();
// Enable "Back" button that was disabled when parcel request was sent.
getChild<LLButton>("back_btn")->setEnabled(TRUE);
@@ -198,12 +204,34 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
}
- if(!parcel_data.sim_name.empty())
- {
- mRegionName->setText(parcel_data.sim_name);
+ S32 region_x;
+ S32 region_y;
+ S32 region_z;
+
+ // If the region position is zero, grab position from the global
+ if (mPosRegion.isExactlyZero())
+ {
+ region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
+ region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
+ region_z = ll_round(parcel_data.global_z);
+ }
+ else
+ {
+ region_x = ll_round(mPosRegion.mV[VX]);
+ region_y = ll_round(mPosRegion.mV[VY]);
+ region_z = ll_round(mPosRegion.mV[VZ]);
+ }
+
+ if (!parcel_data.sim_name.empty())
+ {
+ mRegionTitle = parcel_data.sim_name;
+ std::string name_and_pos = llformat("%s (%d, %d, %d)",
+ mRegionTitle.c_str(), region_x, region_y, region_z);
+ mRegionName->setTextArg("[REGIONAMEPOS]", name_and_pos);
}
else
{
+ mRegionTitle.clear();
mRegionName->setText(LLStringUtil::null);
}
@@ -216,30 +244,11 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mDescEditor->setText(getString("not_available"));
}
- S32 region_x;
- S32 region_y;
- S32 region_z;
-
- // If the region position is zero, grab position from the global
- if(mPosRegion.isExactlyZero())
- {
- region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
- region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
- region_z = ll_round(parcel_data.global_z);
- }
- else
- {
- region_x = ll_round(mPosRegion.mV[VX]);
- region_y = ll_round(mPosRegion.mV[VY]);
- region_z = ll_round(mPosRegion.mV[VZ]);
- }
-
if (!parcel_data.name.empty())
{
mParcelTitle = parcel_data.name;
- mParcelName->setText(llformat("%s (%d, %d, %d)",
- mParcelTitle.c_str(), region_x, region_y, region_z));
+ mParcelName->setText(mParcelTitle);
}
else
{
@@ -280,12 +289,10 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
{
- std::string region_name = mRegionName->getText();
-
LLPickData data;
data.pos_global = pos_global;
- data.name = mParcelTitle.empty() ? region_name : mParcelTitle;
- data.sim_name = region_name;
+ data.name = mParcelTitle.empty() ? mRegionTitle : mParcelTitle;
+ data.sim_name = mRegionTitle;
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 30327378ef..8bf67cfe7d 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -109,6 +109,7 @@ protected:
LLUUID mRequestedID;
LLVector3 mPosRegion;
std::string mParcelTitle; // used for pick title without coordinates
+ std::string mRegionTitle;
std::string mCurrentTitle;
S32 mScrollingPanelMinHeight;
S32 mScrollingPanelWidth;
@@ -120,6 +121,7 @@ protected:
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mRegionName;
LLTextBox* mParcelName;
+ LLTextBox* mParcelOwner;
LLExpandableTextBox* mDescEditor;
LLIconCtrl* mMaturityRatingIcon;
LLTextBox* mMaturityRatingText;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 104316e253..9283dfa218 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -104,8 +104,6 @@ BOOL LLPanelPlaceProfile::postBuild()
mForSalePanel->getChild<LLIconCtrl>("icon_for_sale")->
setMouseDownCallback(boost::bind(&LLPanelPlaceProfile::onForSaleBannerClick, this));
- mParcelOwner = getChild<LLTextBox>("owner_value");
-
mParcelRatingIcon = getChild<LLIconCtrl>("rating_icon");
mParcelRatingText = getChild<LLTextBox>("rating_value");
mVoiceIcon = getChild<LLIconCtrl>("voice_icon");
@@ -183,7 +181,6 @@ void LLPanelPlaceProfile::resetLocation()
mYouAreHerePanel->setVisible(FALSE);
std::string loading = LLTrans::getString("LoadingData");
- mParcelOwner->setValue(loading);
mParcelRatingIcon->setValue(loading);
mParcelRatingText->setText(loading);
@@ -248,14 +245,14 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type)
const S32 SEARCH_DESC_HEIGHT = 150;
// Remember original geometry (once).
- static const S32 sOrigDescVPad = getChildView("parcel_title")->getRect().mBottom - mDescEditor->getRect().mTop;
+ static const S32 sOrigDescVPad = getChildView("owner_label")->getRect().mBottom - mDescEditor->getRect().mTop;
static const S32 sOrigDescHeight = mDescEditor->getRect().getHeight();
static const S32 sOrigMRIconVPad = mDescEditor->getRect().mBottom - mMaturityRatingIcon->getRect().mTop;
static const S32 sOrigMRTextVPad = mDescEditor->getRect().mBottom - mMaturityRatingText->getRect().mTop;
// Resize the description.
const S32 desc_height = is_info_type_agent ? sOrigDescHeight : SEARCH_DESC_HEIGHT;
- const S32 desc_top = getChildView("parcel_title")->getRect().mBottom - sOrigDescVPad;
+ const S32 desc_top = getChildView("owner_label")->getRect().mBottom - sOrigDescVPad;
LLRect desc_rect = mDescEditor->getRect();
desc_rect.setOriginAndSize(desc_rect.mLeft, desc_top - desc_height, desc_rect.getWidth(), desc_height);
mDescEditor->reshape(desc_rect.getWidth(), desc_rect.getHeight());
@@ -401,6 +398,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
parcel_data.global_x = pos_global.mdV[VX];
parcel_data.global_y = pos_global.mdV[VY];
parcel_data.global_z = pos_global.mdV[VZ];
+ parcel_data.owner_id = parcel->getOwnerID();
std::string on = getString("on");
std::string off = getString("off");
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index 3d2654fc12..16478bc179 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -76,8 +76,6 @@ private:
LLPanel* mForSalePanel;
LLPanel* mYouAreHerePanel;
- LLTextBox* mParcelOwner;
-
LLIconCtrl* mParcelRatingIcon;
LLTextBox* mParcelRatingText;
LLIconCtrl* mVoiceIcon;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 961e259947..9c67ec40fe 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -53,12 +53,14 @@
#include "llagentpicksinfo.h"
#include "llavatarpropertiesprocessor.h"
#include "llcommandhandler.h"
+#include "lldndbutton.h"
#include "llfloaterworldmap.h"
#include "llinventorybridge.h"
#include "llinventoryobserver.h"
#include "llinventorymodel.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
+#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
#include "llpanelpick.h"
@@ -78,6 +80,7 @@
static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0;
static const std::string AGENT_INFO_TYPE = "agent";
static const std::string CREATE_LANDMARK_INFO_TYPE = "create_landmark";
+static const std::string CREATE_PICK_TYPE = "create_pick";
static const std::string LANDMARK_INFO_TYPE = "landmark";
static const std::string REMOTE_PLACE_INFO_TYPE = "remote_place";
static const std::string TELEPORT_HISTORY_INFO_TYPE = "teleport_history";
@@ -280,9 +283,6 @@ BOOL LLPanelPlaces::postBuild()
mShowOnMapBtn = getChild<LLButton>("map_btn");
mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
- mEditBtn = getChild<LLButton>("edit_btn");
- mEditBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
-
mSaveBtn = getChild<LLButton>("save_btn");
mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this));
@@ -295,8 +295,25 @@ BOOL LLPanelPlaces::postBuild()
mOverflowBtn = getChild<LLMenuButton>("overflow_btn");
mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
- mPlaceInfoBtn = getChild<LLButton>("profile_btn");
- mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this));
+ mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
+ mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this));
+
+ mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn");
+ mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this));
+
+ mAddMenuButton = getChild<LLMenuButton>("add_menu_btn");
+ mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this));
+
+ mRemoveSelectedBtn = getChild<LLButton>("trash_btn");
+ mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this));
+
+ LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn;
+ trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this
+ , _4 // BOOL drop
+ , _5 // EDragAndDropType cargo_type
+ , _6 // void* cargo_data
+ , _7 // EAcceptance* accept
+ ));
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2));
@@ -325,6 +342,10 @@ BOOL LLPanelPlaces::postBuild()
mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
}
+ mButtonsContainer = getChild<LLPanel>("button_layout_panel");
+ mButtonsContainer->setVisible(FALSE);
+ mFilterContainer = getChild<LLLayoutStack>("top_menu_panel");
+
mFilterEditor = getChild<LLFilterEditor>("Filter");
if (mFilterEditor)
{
@@ -355,6 +376,9 @@ BOOL LLPanelPlaces::postBuild()
LLComboBox* folder_combo = mLandmarkInfo->getChild<LLComboBox>("folder_combo");
folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
+ LLButton* edit_btn = mLandmarkInfo->getChild<LLButton>("edit_btn");
+ edit_btn->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
+
createTabs();
updateVerbs();
@@ -387,7 +411,22 @@ void LLPanelPlaces::onOpen(const LLSD& key)
// Update the buttons at the bottom of the panel
updateVerbs();
}
- else
+ else if (key_type == CREATE_PICK_TYPE)
+ {
+ LLUUID item_id = key["item_id"];
+
+ LLLandmarksPanel* landmarks_panel =
+ dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+ if (landmarks_panel && item_id.notNull())
+ {
+ LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id));
+ if (landmark)
+ {
+ landmarks_panel->doCreatePick(landmark, item_id);
+ }
+ }
+ }
+ else // "create_landmark"
{
mFilterEditor->clear();
onFilterEdit("", false);
@@ -408,7 +447,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
}
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
{
- mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+ LLUUID dest_folder = key["dest_folder"];
+ mLandmarkInfo->setInfoAndCreateLandmark(dest_folder);
if (key.has("x") && key.has("y") && key.has("z"))
{
@@ -532,7 +572,6 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
BOOL is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) &&
mItem->getPermissions().allowModifyBy(gAgent.getID());
- mEditBtn->setEnabled(is_landmark_editable);
mSaveBtn->setEnabled(is_landmark_editable);
if (is_landmark_editable)
@@ -612,6 +651,23 @@ void LLPanelPlaces::onTabSelected()
onFilterEdit(mActivePanel->getFilterSubString(), true);
mActivePanel->updateVerbs();
+
+ // History panel does not support deletion nor creation
+ // Hide menus
+ bool supports_create = mActivePanel->getCreateMenu() != NULL;
+ childSetVisible("add_btn_panel", supports_create);
+
+ // favorites and inventory can remove items, history can clear history
+ childSetVisible("trash_btn_panel", TRUE);
+
+ if (supports_create)
+ {
+ mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items"));
+ }
+ else
+ {
+ mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history"));
+ }
}
void LLPanelPlaces::onTeleportButtonClicked()
@@ -675,6 +731,12 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
+ if (mItem.isNull())
+ {
+ LL_WARNS() << "NULL landmark item" << LL_ENDL;
+ llassert(mItem.notNull());
+ return;
+ }
LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID());
if (!landmark)
return;
@@ -722,34 +784,6 @@ void LLPanelPlaces::onEditButtonClicked()
updateVerbs();
}
-class LLUpdateLandmarkParent : public LLInventoryCallback
-{
-public:
- LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
- mItem(item),
- mNewParentId(new_parent)
- {};
- /* virtual */ void fire(const LLUUID& inv_item_id)
- {
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
- update.push_back(new_folder);
- gInventory.accountForUpdate(update);
-
- mItem->setParent(mNewParentId);
- mItem->updateParentOnServer(FALSE);
-
- gInventory.updateItem(mItem);
- gInventory.notifyObservers();
- }
-
-private:
- LLPointer<LLViewerInventoryItem> mItem;
- LLUUID mNewParentId;
-};
-
void LLPanelPlaces::onSaveButtonClicked()
{
if (!mLandmarkInfo || mItem.isNull())
@@ -879,14 +913,6 @@ void LLPanelPlaces::onOverflowButtonClicked()
mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT);
}
-void LLPanelPlaces::onProfileButtonClicked()
-{
- if (!mActivePanel)
- return;
-
- mActivePanel->onShowProfile();
-}
-
bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param)
{
std::string value = param.asString();
@@ -975,6 +1001,50 @@ void LLPanelPlaces::onBackButtonClicked()
updateVerbs();
}
+void LLPanelPlaces::onGearMenuClick()
+{
+ if (mActivePanel)
+ {
+ LLToggleableMenu* menu = mActivePanel->getSelectionMenu();
+ mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
+}
+
+void LLPanelPlaces::onSortingMenuClick()
+{
+ if (mActivePanel)
+ {
+ LLToggleableMenu* menu = mActivePanel->getSortingMenu();
+ mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
+}
+
+void LLPanelPlaces::onAddMenuClick()
+{
+ if (mActivePanel)
+ {
+ LLToggleableMenu* menu = mActivePanel->getCreateMenu();
+ mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
+}
+
+void LLPanelPlaces::onRemoveButtonClicked()
+{
+ if (mActivePanel)
+ {
+ mActivePanel->onRemoveSelected();
+ }
+}
+
+bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept)
+{
+ if (mActivePanel)
+ {
+ return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept);
+ }
+ return false;
+}
+
void LLPanelPlaces::togglePickPanel(BOOL visible)
{
if (mPickPanel)
@@ -991,8 +1061,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
if (!mPlaceProfile || !mLandmarkInfo)
return;
- mFilterEditor->setVisible(!visible);
mTabContainer->setVisible(!visible);
+ mButtonsContainer->setVisible(visible);
+ mFilterContainer->setVisible(!visible);
if (mPlaceInfoType == AGENT_INFO_TYPE ||
mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
@@ -1008,10 +1079,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
// to avoid text blinking.
mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
- LLRect rect = getRect();
- LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
- mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight());
-
mLandmarkInfo->setVisible(FALSE);
}
else if (mPlaceInfoType == AGENT_INFO_TYPE)
@@ -1032,15 +1099,19 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
if (visible)
{
mLandmarkInfo->resetLocation();
-
- LLRect rect = getRect();
- LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
- mLandmarkInfo->reshape(new_rect.getWidth(), new_rect.getHeight());
}
else
{
- LLLandmarksPanel* landmarks_panel =
- dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+ std::string tab_panel_name("Landmarks");
+ if (mItem.notNull())
+ {
+ if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))
+ {
+ tab_panel_name = "Favorites";
+ }
+ }
+
+ LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName(tab_panel_name));
if (landmarks_panel)
{
// If a landmark info is being closed we open the landmarks tab
@@ -1050,6 +1121,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
landmarks_panel->setItemSelected(mItem->getUUID(), TRUE);
}
+ else
+ {
+ landmarks_panel->resetSelection();
+ }
}
}
}
@@ -1117,11 +1192,19 @@ void LLPanelPlaces::createTabs()
if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated))
return;
+ LLFavoritesPanel* favorites_panel = new LLFavoritesPanel();
+ if (favorites_panel)
+ {
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(favorites_panel).
+ label(getString("favorites_tab_title")).
+ insert_at(LLTabContainer::END));
+ }
+
LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel();
if (landmarks_panel)
{
- landmarks_panel->setPanelPlacesButtons(this);
-
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(landmarks_panel).
@@ -1132,8 +1215,6 @@ void LLPanelPlaces::createTabs()
LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel();
if (teleport_history_panel)
{
- teleport_history_panel->setPanelPlacesButtons(this);
-
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(teleport_history_panel).
@@ -1145,9 +1226,31 @@ void LLPanelPlaces::createTabs()
mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
- // Filter applied to show all items.
- if (mActivePanel)
- mActivePanel->onSearchEdit(mActivePanel->getFilterSubString());
+ if (mActivePanel)
+ {
+ // Filter applied to show all items.
+ mActivePanel->onSearchEdit(mActivePanel->getFilterSubString());
+
+ // History panel does not support deletion nor creation
+ // Hide menus
+ bool supports_create = mActivePanel->getCreateMenu() != NULL;
+ childSetVisible("add_btn_panel", supports_create);
+
+ // favorites and inventory can remove items, history can clear history
+ childSetVisible("trash_btn_panel", TRUE);
+
+ if (supports_create)
+ {
+ mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items"));
+ }
+ else
+ {
+ mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history"));
+ }
+
+ mActivePanel->setRemoveBtn(mRemoveSelectedBtn);
+ mActivePanel->updateVerbs();
+ }
mTabsCreated = true;
}
@@ -1210,14 +1313,14 @@ void LLPanelPlaces::updateVerbs()
mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
- mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
- mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
+ bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;
+ mOverflowBtn->setVisible(show_options_btn);
+ getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);
+ getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn);
if (is_place_info_visible)
{
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 27f991c202..3b87eb6cb9 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -48,6 +48,7 @@ class LLRemoteParcelInfoObserver;
class LLTabContainer;
class LLToggleableMenu;
class LLMenuButton;
+class LLLayoutStack;
typedef std::pair<LLUUID, std::string> folder_pair_t;
@@ -96,7 +97,12 @@ private:
bool onOverflowMenuItemEnable(const LLSD& param);
void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
- void onProfileButtonClicked();
+ void onGearMenuClick();
+ void onSortingMenuClick();
+ void onAddMenuClick();
+ void onRemoveButtonClicked();
+ bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
+
void toggleMediaPanel();
void togglePickPanel(BOOL visible);
@@ -111,6 +117,8 @@ private:
LLFilterEditor* mFilterEditor;
LLPanelPlacesTab* mActivePanel;
LLTabContainer* mTabContainer;
+ LLPanel* mButtonsContainer;
+ LLLayoutStack* mFilterContainer;
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
@@ -121,12 +129,16 @@ private:
LLButton* mPlaceProfileBackBtn;
LLButton* mTeleportBtn;
LLButton* mShowOnMapBtn;
- LLButton* mEditBtn;
LLButton* mSaveBtn;
LLButton* mCancelBtn;
LLButton* mCloseBtn;
LLMenuButton* mOverflowBtn;
- LLButton* mPlaceInfoBtn;
+
+ // Top menu
+ LLMenuButton* mGearMenuButton;
+ LLMenuButton* mSortingMenuButton;
+ LLMenuButton* mAddMenuButton;
+ LLButton* mRemoveSelectedBtn;
LLPlacesInventoryObserver* mInventoryObserver;
LLPlacesParcelObserver* mParcelObserver;
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index 9644b7518e..748a917147 100644
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
@@ -38,6 +38,7 @@
#include "llworldmap.h"
std::string LLPanelPlacesTab::sFilterSubString = LLStringUtil::null;
+LLButton* LLPanelPlacesTab::sRemoveBtn = NULL;
bool LLPanelPlacesTab::isTabVisible()
{
@@ -47,13 +48,6 @@ bool LLPanelPlacesTab::isTabVisible()
return true;
}
-void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
-{
- mTeleportBtn = panel->getChild<LLButton>("teleport_btn");
- mShowOnMapBtn = panel->getChild<LLButton>("map_btn");
- mShowProfile = panel->getChild<LLButton>("profile_btn");
-}
-
void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,
U64 region_handle,
const std::string& url,
diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h
index 367ce46e2e..aab1c130c1 100644
--- a/indra/newview/llpanelplacestab.h
+++ b/indra/newview/llpanelplacestab.h
@@ -30,6 +30,7 @@
#include "llpanel.h"
class LLPanelPlaces;
+class LLToggleableMenu;
class LLPanelPlacesTab : public LLPanel
{
@@ -42,11 +43,21 @@ public:
virtual void onShowOnMap() = 0;
virtual void onShowProfile() = 0;
virtual void onTeleport() = 0;
+ virtual void onRemoveSelected() = 0;
virtual bool isSingleItemSelected() = 0;
+ // returns menu for current selection
+ virtual LLToggleableMenu* getSelectionMenu() = 0;
+ virtual LLToggleableMenu* getSortingMenu() = 0;
+ virtual LLToggleableMenu* getCreateMenu() = 0;
+
+ /**
+ * Processes drag-n-drop of the Landmarks and folders into trash button.
+ */
+ virtual bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) = 0;
+
bool isTabVisible(); // Check if parent TabContainer is visible.
- void setPanelPlacesButtons(LLPanelPlaces* panel);
void onRegionResponse(const LLVector3d& landmark_global_pos,
U64 region_handle,
const std::string& url,
@@ -56,13 +67,12 @@ public:
const std::string& getFilterSubString() { return sFilterSubString; }
void setFilterSubString(const std::string& string) { sFilterSubString = string; }
-protected:
- LLButton* mTeleportBtn;
- LLButton* mShowOnMapBtn;
- LLButton* mShowProfile;
+ void setRemoveBtn(LLButton* trash_btn) { sRemoveBtn = trash_btn; }
+protected:
// Search string for filtering landmarks and teleport history locations
static std::string sFilterSubString;
+ static LLButton* sRemoveBtn;
};
#endif //LL_LLPANELPLACESTAB_H
diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp
new file mode 100644
index 0000000000..183123e534
--- /dev/null
+++ b/indra/newview/llpanelpresetscamerapulldown.cpp
@@ -0,0 +1,149 @@
+/**
+ * @file llpanelpresetscamerapulldown.cpp
+ * @brief A panel showing a quick way to pick camera presets
+ *
+ * $LicenseInfo:firstyear=2017&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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 "llpanelpresetscamerapulldown.h"
+
+#include "llviewercontrol.h"
+#include "llstatusbar.h"
+
+#include "llbutton.h"
+#include "lltabcontainer.h"
+#include "llfloatercamera.h"
+#include "llfloaterreg.h"
+#include "llfloaterpreference.h"
+#include "llpresetsmanager.h"
+#include "llsliderctrl.h"
+#include "llscrolllistctrl.h"
+#include "lltrans.h"
+
+///----------------------------------------------------------------------------
+/// Class LLPanelPresetsCameraPulldown
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLPanelPresetsCameraPulldown::LLPanelPresetsCameraPulldown()
+{
+ mCommitCallbackRegistrar.add("Presets.toggleCameraFloater", boost::bind(&LLPanelPresetsCameraPulldown::onViewButtonClick, this, _2));
+ mCommitCallbackRegistrar.add("PresetsCamera.RowClick", boost::bind(&LLPanelPresetsCameraPulldown::onRowClick, this, _2));
+
+ buildFromFile( "panel_presets_camera_pulldown.xml");
+}
+
+BOOL LLPanelPresetsCameraPulldown::postBuild()
+{
+ LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
+ if (presetsMgr)
+ {
+ // Make sure there is a default preference file
+ presetsMgr->createMissingDefault(PRESETS_CAMERA);
+
+ presetsMgr->startWatching(PRESETS_CAMERA);
+
+ presetsMgr->setPresetListChangeCameraCallback(boost::bind(&LLPanelPresetsCameraPulldown::populatePanel, this));
+ }
+
+ populatePanel();
+
+ return LLPanelPulldown::postBuild();
+}
+
+void LLPanelPresetsCameraPulldown::populatePanel()
+{
+ LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_CAMERA, mPresetNames, DEFAULT_BOTTOM);
+
+ LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_camera_list");
+
+ if (scroll && mPresetNames.begin() != mPresetNames.end())
+ {
+ scroll->clearRows();
+
+ std::string active_preset = gSavedSettings.getString("PresetCameraActive");
+ if (active_preset == PRESETS_DEFAULT)
+ {
+ active_preset = LLTrans::getString(PRESETS_DEFAULT);
+ }
+
+ for (std::list<std::string>::const_iterator it = mPresetNames.begin(); it != mPresetNames.end(); ++it)
+ {
+ const std::string& name = *it;
+ LL_DEBUGS() << "adding '" << name << "'" << LL_ENDL;
+
+ LLSD row;
+ row["columns"][0]["column"] = "preset_name";
+ row["columns"][0]["value"] = name;
+
+ bool is_selected_preset = false;
+ if (name == active_preset)
+ {
+ row["columns"][1]["column"] = "icon";
+ row["columns"][1]["type"] = "icon";
+ row["columns"][1]["value"] = "Check_Mark";
+
+ is_selected_preset = true;
+ }
+
+ LLScrollListItem* new_item = scroll->addElement(row);
+ new_item->setSelected(is_selected_preset);
+ }
+ }
+}
+
+void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
+{
+ LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_camera_list");
+
+ if (scroll)
+ {
+ LLScrollListItem* item = scroll->getFirstSelected();
+ if (item)
+ {
+ std::string name = item->getColumn(1)->getValue().asString();
+
+ LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
+ LLFloaterCamera::switchToPreset(name);
+
+ setVisible(FALSE);
+ }
+ else
+ {
+ LL_DEBUGS() << "none selected" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_DEBUGS() << "no scroll" << LL_ENDL;
+ }
+}
+
+void LLPanelPresetsCameraPulldown::onViewButtonClick(const LLSD& user_data)
+{
+ // close the minicontrol, we're bringing up the big one
+ setVisible(FALSE);
+
+ LLFloaterReg::toggleInstanceOrBringToFront("camera");
+}
diff --git a/indra/newview/llpanelpresetscamerapulldown.h b/indra/newview/llpanelpresetscamerapulldown.h
new file mode 100644
index 0000000000..c49bab042e
--- /dev/null
+++ b/indra/newview/llpanelpresetscamerapulldown.h
@@ -0,0 +1,49 @@
+/**
+ * @file llpanelpresetscamerapulldown.h
+ * @brief A panel showing a quick way to pick camera presets
+ *
+ * $LicenseInfo:firstyear=2017&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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_LLPANELPRESETSCAMERAPULLDOWN_H
+#define LL_LLPANELPRESETSCAMERAPULLDOWN_H
+
+#include "linden_common.h"
+
+#include "llpanelpulldown.h"
+
+class LLPanelPresetsCameraPulldown : public LLPanelPulldown
+{
+ public:
+ LLPanelPresetsCameraPulldown();
+ /*virtual*/ BOOL postBuild();
+ void populatePanel();
+
+ private:
+ void onViewButtonClick(const LLSD& user_data);
+ void onRowClick(const LLSD& user_data);
+
+ std::list<std::string> mPresetNames;
+ LOG_CLASS(LLPanelPresetsCameraPulldown);
+};
+
+#endif // LL_LLPANELPRESETSCAMERAPULLDOWN_H
diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp
index 9b4dc5474a..d52ad8056f 100644
--- a/indra/newview/llpanelpresetspulldown.cpp
+++ b/indra/newview/llpanelpresetspulldown.cpp
@@ -33,16 +33,13 @@
#include "llbutton.h"
#include "lltabcontainer.h"
+#include "llfloater.h"
#include "llfloaterreg.h"
-#include "llfloaterpreference.h"
#include "llpresetsmanager.h"
#include "llsliderctrl.h"
#include "llscrolllistctrl.h"
#include "lltrans.h"
-/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseFadeStartTimeSec = 2.0f;
-/* static */ const F32 LLPanelPresetsPulldown::sAutoCloseTotalTimeSec = 3.0f;
-
///----------------------------------------------------------------------------
/// Class LLPanelPresetsPulldown
///----------------------------------------------------------------------------
@@ -63,17 +60,16 @@ BOOL LLPanelPresetsPulldown::postBuild()
LLPresetsManager* presetsMgr = LLPresetsManager::getInstance();
presetsMgr->setPresetListChangeCallback(boost::bind(&LLPanelPresetsPulldown::populatePanel, this));
// Make sure there is a default preference file
- presetsMgr->createMissingDefault();
+ presetsMgr->createMissingDefault(PRESETS_GRAPHIC);
populatePanel();
- return LLPanel::postBuild();
+ return LLPanelPulldown::postBuild();
}
void LLPanelPresetsPulldown::populatePanel()
{
- std::string presets_dir = LLPresetsManager::getInstance()->getPresetsDir(PRESETS_GRAPHIC);
- LLPresetsManager::getInstance()->loadPresetNamesFromDir(presets_dir, mPresetNames, DEFAULT_TOP);
+ LLPresetsManager::getInstance()->loadPresetNamesFromDir(PRESETS_GRAPHIC, mPresetNames, DEFAULT_TOP);
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_list");
@@ -112,61 +108,6 @@ void LLPanelPresetsPulldown::populatePanel()
}
}
-/*virtual*/
-void LLPanelPresetsPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.stop();
- LLPanel::onMouseEnter(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelPresetsPulldown::onTopLost()
-{
- setVisible(FALSE);
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- LLPanel::handleMouseDown(x,y,mask);
- return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- LLPanel::handleRightMouseDown(x, y, mask);
- return TRUE;
-}
-
-/*virtual*/
-BOOL LLPanelPresetsPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
- LLPanel::handleDoubleClick(x, y, mask);
- return TRUE;
-}
-
-/*virtual*/
-void LLPanelPresetsPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.start();
- LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelPresetsPulldown::onVisibilityChange ( BOOL new_visibility )
-{
- if (new_visibility)
- {
- mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
- }
- else
- {
- mHoverTimer.stop();
-
- }
-}
-
void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
{
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("preset_list");
@@ -213,19 +154,3 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)
}
}
}
-
-//virtual
-void LLPanelPresetsPulldown::draw()
-{
- F32 alpha = mHoverTimer.getStarted()
- ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
- : 1.0f;
- LLViewDrawContext context(alpha);
-
- LLPanel::draw();
-
- if (alpha == 0.f)
- {
- setVisible(FALSE);
- }
-}
diff --git a/indra/newview/llpanelpresetspulldown.h b/indra/newview/llpanelpresetspulldown.h
index 322bf5a58f..c0d32b9b21 100644
--- a/indra/newview/llpanelpresetspulldown.h
+++ b/indra/newview/llpanelpresetspulldown.h
@@ -29,22 +29,13 @@
#include "linden_common.h"
-#include "llpanel.h"
+#include "llpanelpulldown.h"
-class LLFrameTimer;
-class LLPanelPresetsPulldown : public LLPanel
+class LLPanelPresetsPulldown : public LLPanelPulldown
{
public:
LLPanelPresetsPulldown();
- /*virtual*/ void draw();
- /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
- /*virtual*/ void onTopLost();
- /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
/*virtual*/ BOOL postBuild();
void populatePanel();
@@ -53,9 +44,6 @@ class LLPanelPresetsPulldown : public LLPanel
void onRowClick(const LLSD& user_data);
std::list<std::string> mPresetNames;
- LLFrameTimer mHoverTimer;
- static const F32 sAutoCloseFadeStartTimeSec;
- static const F32 sAutoCloseTotalTimeSec;
LOG_CLASS(LLPanelPresetsPulldown);
};
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 8105beae1b..c42cd6c6ba 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -64,8 +64,8 @@
#include "llvector4a.h"
// Functions pulled from pipeline.cpp
-glh::matrix4f glh_get_current_modelview();
-glh::matrix4f glh_get_current_projection();
+glh::matrix4f get_current_modelview();
+glh::matrix4f get_current_projection();
// Functions pulled from llviewerdisplay.cpp
bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model);
@@ -73,6 +73,9 @@ bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model);
const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM };
const int LLPanelPrimMediaControls::kNumZoomLevels = 2;
+const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f;
+const S32 ADDR_LEFT_PAD = 3;
+
//
// LLPanelPrimMediaControls
//
@@ -93,6 +96,7 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
mZoomObjectID(LLUUID::null),
mZoomObjectFace(0),
mVolumeSliderVisible(0),
+ mZoomedCameraPos(),
mWindowShade(NULL),
mHideImmediately(false),
mSecureURL(false),
@@ -154,7 +158,7 @@ BOOL LLPanelPrimMediaControls::postBuild()
mMediaProgressPanel = getChild<LLPanel>("media_progress_indicator");
mMediaProgressBar = getChild<LLProgressBar>("media_progress_bar");
mMediaAddressCtrl = getChild<LLUICtrl>("media_address");
- mMediaAddress = getChild<LLUICtrl>("media_address_url");
+ mMediaAddress = getChild<LLLineEditor>("media_address_url");
mMediaPlaySliderPanel = getChild<LLUICtrl>("media_play_position");
mMediaPlaySliderCtrl = getChild<LLUICtrl>("media_play_slider");
mSkipFwdCtrl = getChild<LLUICtrl>("skip_forward");
@@ -256,7 +260,7 @@ void LLPanelPrimMediaControls::focusOnTarget()
LLViewerMediaImpl* media_impl = getTargetMediaImpl();
if(media_impl)
{
- if(!media_impl->hasFocus())
+ if (!media_impl->hasFocus())
{
// The current target doesn't have media focus -- focus on it.
LLViewerObject* objectp = getTargetObject();
@@ -307,7 +311,8 @@ void LLPanelPrimMediaControls::updateShape()
bool can_navigate = parcel->getMediaAllowNavigate();
bool enabled = false;
- bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace);
+ bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace) && !isZoomDistExceeding();
+
// There is no such thing as "has_focus" being different from normal controls set
// anymore (as of user feedback from bri 10/09). So we cheat here and force 'has_focus'
// to 'true' (or, actually, we use a setting)
@@ -498,8 +503,10 @@ void LLPanelPrimMediaControls::updateShape()
std::string test_prefix = mCurrentURL.substr(0, prefix.length());
LLStringUtil::toLower(test_prefix);
mSecureURL = has_focus && (test_prefix == prefix);
- mCurrentURL = (mSecureURL ? " " + mCurrentURL : mCurrentURL);
-
+
+ S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD;
+ mMediaAddress->setTextPadding(left_pad, 0);
+
if(mCurrentURL!=mPreviousURL)
{
setCurrentURL();
@@ -547,17 +554,17 @@ void LLPanelPrimMediaControls::updateShape()
switch (mScrollState)
{
case SCROLL_UP:
- media_impl->scrollWheel(0, -1, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
break;
case SCROLL_DOWN:
- media_impl->scrollWheel(0, 1, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
break;
case SCROLL_LEFT:
- media_impl->scrollWheel(1, 0, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
break;
case SCROLL_RIGHT:
- media_impl->scrollWheel(-1, 0, MASK_NONE);
+ media_impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
break;
case SCROLL_NONE:
@@ -642,7 +649,7 @@ void LLPanelPrimMediaControls::updateShape()
glh::matrix4f mat;
if (!is_hud)
{
- mat = glh_get_current_projection() * glh_get_current_modelview();
+ mat = get_current_projection() * get_current_modelview();
}
else {
glh::matrix4f proj, modelview;
@@ -829,8 +836,32 @@ void LLPanelPrimMediaControls::draw()
BOOL LLPanelPrimMediaControls::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- mInactivityTimer.start();
- return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
+ mInactivityTimer.start();
+ BOOL res = FALSE;
+
+ // Unlike other mouse events, we need to handle scroll here otherwise
+ // it will be intercepted by camera and won't reach toolpie
+ if (LLViewerMediaFocus::getInstance()->isHoveringOverFocused())
+ {
+ // either let toolpie handle this or expose mHoverPick.mUVCoords in some way
+ res = LLToolPie::getInstance()->handleScrollWheel(x, y, clicks);
+ }
+
+ return res;
+}
+
+BOOL LLPanelPrimMediaControls::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ mInactivityTimer.start();
+ BOOL res = FALSE;
+
+ if (LLViewerMediaFocus::getInstance()->isHoveringOverFocused())
+ {
+ // either let toolpie handle this or expose mHoverPick.mUVCoords in some way
+ res = LLToolPie::getInstance()->handleScrollHWheel(x, y, clicks);
+ }
+
+ return res;
}
BOOL LLPanelPrimMediaControls::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1117,7 +1148,7 @@ void LLPanelPrimMediaControls::updateZoom()
if (zoom_padding > 0.0f)
{
// since we only zoom into medium for now, always set zoom_in constraint to true
- LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true);
+ mZoomedCameraPos = LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true);
}
// Remember the object ID/face we zoomed into, so we can update the zoom icon appropriately
@@ -1134,7 +1165,7 @@ void LLPanelPrimMediaControls::onScrollUp(void* user_data)
if(impl)
{
- impl->scrollWheel(0, -1, MASK_NONE);
+ impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollUpHeld(void* user_data)
@@ -1151,7 +1182,7 @@ void LLPanelPrimMediaControls::onScrollRight(void* user_data)
if(impl)
{
- impl->scrollWheel(-1, 0, MASK_NONE);
+ impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
}
}
@@ -1170,7 +1201,7 @@ void LLPanelPrimMediaControls::onScrollLeft(void* user_data)
if(impl)
{
- impl->scrollWheel(1, 0, MASK_NONE);
+ impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_LEFT, MASK_NONE);
}
}
@@ -1189,7 +1220,7 @@ void LLPanelPrimMediaControls::onScrollDown(void* user_data)
if(impl)
{
- impl->scrollWheel(0, 1, MASK_NONE);
+ impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollDownHeld(void* user_data)
@@ -1377,6 +1408,10 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()
return mVolumeSliderVisible > 0;
}
+bool LLPanelPrimMediaControls::isZoomDistExceeding()
+{
+ return (gAgentCamera.getCameraPositionGlobal() - mZoomedCameraPos).normalize() >= EXCEEDING_ZOOM_DISTANCE;
+}
void LLPanelPrimMediaControls::clearFaceOnFade()
{
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index 21d5236074..dd0e4ff095 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -39,6 +39,7 @@ class LLProgressBar;
class LLSliderCtrl;
class LLViewerMediaImpl;
class LLWindowShade;
+class LLLineEditor;
class LLPanelPrimMediaControls : public LLPanel
{
@@ -48,6 +49,7 @@ public:
/*virtual*/ BOOL postBuild();
virtual void draw();
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -118,6 +120,8 @@ private:
void showVolumeSlider();
void hideVolumeSlider();
bool shouldVolumeSliderBeVisible();
+
+ bool isZoomDistExceeding();
static void onScrollUp(void* user_data);
static void onScrollUpHeld(void* user_data);
@@ -161,7 +165,7 @@ private:
LLPanel *mMediaProgressPanel;
LLProgressBar *mMediaProgressBar;
LLUICtrl *mMediaAddressCtrl;
- LLUICtrl *mMediaAddress;
+ LLLineEditor *mMediaAddress;
LLUICtrl *mMediaPlaySliderPanel;
LLUICtrl *mMediaPlaySliderCtrl;
LLUICtrl *mVolumeCtrl;
@@ -182,6 +186,8 @@ private:
F32 mZoomMediumPadding;
F32 mZoomFarPadding;
S32 mTopWorldViewAvoidZone;
+
+ LLVector3d mZoomedCameraPos;
LLUICtrl *mMediaPanelScroll;
LLButton *mScrollUpCtrl;
diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp
new file mode 100644
index 0000000000..4de6ee8182
--- /dev/null
+++ b/indra/newview/llpanelpulldown.cpp
@@ -0,0 +1,118 @@
+/**
+* @file llpanelpulldown.cpp
+* @brief A panel that serves as a basis for multiple toolbar pulldown panels
+*
+* $LicenseInfo:firstyear=2020&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2020, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelpulldown.h"
+
+const F32 AUTO_CLOSE_FADE_TIME_START_SEC = 2.0f;
+const F32 AUTO_CLOSE_FADE_TIME_END_SEC = 3.0f;
+
+///----------------------------------------------------------------------------
+/// Class LLPanelPresetsCameraPulldown
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLPanelPulldown::LLPanelPulldown()
+{
+ mHoverTimer.stop();
+}
+
+/*virtual*/
+void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mHoverTimer.stop();
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+/*virtual*/
+void LLPanelPulldown::onTopLost()
+{
+ setVisible(FALSE);
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLPanel::handleMouseDown(x, y, mask);
+ return TRUE;
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLPanel::handleRightMouseDown(x, y, mask);
+ return TRUE;
+}
+
+/*virtual*/
+BOOL LLPanelPulldown::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ LLPanel::handleDoubleClick(x, y, mask);
+ return TRUE;
+}
+
+BOOL LLPanelPulldown::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ LLPanel::handleScrollWheel(x, y, clicks);
+ return TRUE; //If we got here, then we are in Pulldown's rect, consume the event.
+}
+
+/*virtual*/
+void LLPanelPulldown::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mHoverTimer.start();
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+/*virtual*/
+void LLPanelPulldown::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility)
+ {
+ mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
+ }
+ else
+ {
+ mHoverTimer.stop();
+ }
+}
+
+//virtual
+void LLPanelPulldown::draw()
+{
+ F32 alpha = mHoverTimer.getStarted()
+ ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START_SEC, AUTO_CLOSE_FADE_TIME_END_SEC, 1.f, 0.f)
+ : 1.0f;
+ LLViewDrawContext context(alpha);
+
+ LLPanel::draw();
+
+ if (alpha == 0.f)
+ {
+ setVisible(FALSE);
+ }
+}
diff --git a/indra/newview/llpanelpulldown.h b/indra/newview/llpanelpulldown.h
new file mode 100644
index 0000000000..705e76d0ab
--- /dev/null
+++ b/indra/newview/llpanelpulldown.h
@@ -0,0 +1,55 @@
+/**
+ * @file llpanelpulldown.h
+ * @brief A panel that serves as a basis for multiple toolbar pulldown panels
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELPULLDOWN_H
+#define LL_LLPANELPULLDOWN_H
+
+#include "linden_common.h"
+
+#include "llpanel.h"
+
+class LLFrameTimer;
+
+class LLPanelPulldown : public LLPanel
+{
+public:
+ LLPanelPulldown();
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ /*virtual*/ void onTopLost();
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
+
+ /*virtual*/ void draw();
+
+protected:
+ LLFrameTimer mHoverTimer;
+};
+
+#endif // LL_LLPANELPULLDOWN_H
diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index a17e3f9e78..c3524a8c87 100644
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
@@ -39,6 +39,8 @@
#include "llsidetraypanelcontainer.h"
#include "llviewercontrol.h" // gSavedSettings
+#include "llagentbenefits.h"
+
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
S32 power_of_two(S32 sz, S32 upper)
@@ -59,6 +61,7 @@ LLPanelSnapshot::LLPanelSnapshot()
// virtual
BOOL LLPanelSnapshot::postBuild()
{
+ getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));
if (!getWidthSpinnerName().empty())
{
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index 21ac7604ff..9e56a04b3b 100644
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -27,7 +27,6 @@
#include "llviewerprecompiledheaders.h"
#include "llcombobox.h"
-#include "lleconomy.h"
#include "llsidetraypanelcontainer.h"
#include "llspinctrl.h"
@@ -38,6 +37,8 @@
#include "llstatusbar.h" // can_afford_transaction()
#include "llnotificationsutil.h"
+#include "llagentbenefits.h"
+
/**
* The panel provides UI for saving snapshot as an inventory texture.
*/
@@ -135,7 +136,6 @@ BOOL LLPanelSnapshotInventory::postBuild()
// virtual
void LLPanelSnapshotInventory::onOpen(const LLSD& key)
{
- getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload()));
LLPanelSnapshot::onOpen(key);
}
@@ -155,7 +155,7 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
void LLPanelSnapshotInventoryBase::onSend()
{
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
if (can_afford_transaction(expected_upload_cost))
{
if (mSnapshotFloater)
@@ -191,7 +191,7 @@ BOOL LLPanelOutfitSnapshotInventory::postBuild()
// virtual
void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key)
{
- getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload()));
+ getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost()));
LLPanelSnapshot::onOpen(key);
}
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 1a3e946127..8cc2fbc770 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -26,19 +26,20 @@
#include "llviewerprecompiledheaders.h"
-#include "lleconomy.h"
#include "llpanel.h"
#include "llsidetraypanelcontainer.h"
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
#include "llfloaterreg.h"
+#include "llagentbenefits.h"
+
+
/**
* Provides several ways to save a snapshot.
*/
class LLPanelSnapshotOptions
: public LLPanel
-, public LLEconomyObserver
{
LOG_CLASS(LLPanelSnapshotOptions);
@@ -47,7 +48,6 @@ public:
~LLPanelSnapshotOptions();
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onEconomyDataChange() { updateUploadCost(); }
private:
void updateUploadCost();
@@ -68,13 +68,10 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
-
- LLGlobalEconomy::getInstance()->addObserver(this);
}
LLPanelSnapshotOptions::~LLPanelSnapshotOptions()
{
- LLGlobalEconomy::getInstance()->removeObserver(this);
}
// virtual
@@ -92,7 +89,7 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key)
void LLPanelSnapshotOptions::updateUploadCost()
{
- S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost));
}
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index f3a4cf36ee..b8aa976657 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -170,14 +170,16 @@ void LLPanelSnapshotPostcard::sendPostcard()
std::string url = gAgent.getRegion()->getCapability("SendPostcard");
if (!url.empty())
{
- LLResourceUploadInfo::ptr_t uploadInfo(new LLPostcardUploadInfo(
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLPostcardUploadInfo>(
getChild<LLUICtrl>("name_form")->getValue().asString(),
getChild<LLUICtrl>("to_form")->getValue().asString(),
getChild<LLUICtrl>("subject_form")->getValue().asString(),
getChild<LLUICtrl>("msg_form")->getValue().asString(),
mSnapshotFloater->getPosTakenGlobal(),
mSnapshotFloater->getImageData(),
- boost::bind(&LLPanelSnapshotPostcard::sendPostcardFinished, _4)));
+ [](LLUUID, LLUUID, LLUUID, LLSD response) {
+ LLPanelSnapshotPostcard::sendPostcardFinished(response);
+ }));
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index fe0608d544..b938b30479 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -56,7 +56,7 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
class LLTeleportHistoryFlatItem : public LLPanel
{
public:
- LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
+ LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string &region_name,
LLDate date, const std::string &hl);
virtual ~LLTeleportHistoryFlatItem();
@@ -86,12 +86,13 @@ public:
private:
void onProfileBtnClick();
+ void showMenu(S32 x, S32 y);
LLButton* mProfileBtn;
LLTextBox* mTitle;
LLTextBox* mTimeTextBox;
- LLTeleportHistoryPanel::ContextMenu *mContextMenu;
+ LLToggleableMenu *mMenu;
S32 mIndex;
std::string mRegionName;
@@ -112,7 +113,7 @@ protected:
public:
LLTeleportHistoryFlatItem* getFlatItemForPersistentItem (
- LLTeleportHistoryPanel::ContextMenu *context_menu,
+ LLToggleableMenu *menu,
const LLTeleportHistoryPersistentItem& persistent_item,
const S32 cur_item_index,
const std::string &hl);
@@ -130,16 +131,16 @@ private:
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string &region_name,
LLDate date, const std::string &hl)
: LLPanel(),
mIndex(index),
- mContextMenu(context_menu),
+ mMenu(menu),
mRegionName(region_name),
mDate(date),
mHighlight(hl)
{
- buildFromFile( "panel_teleport_history_item.xml");
+ buildFromFile("panel_teleport_history_item.xml");
}
LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem()
@@ -266,10 +267,9 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
// virtual
BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mContextMenu)
- mContextMenu->show(this, mIndex, x, y);
-
- return LLPanel::handleRightMouseDown(x, y, mask);
+ LLPanel::handleRightMouseDown(x, y, mask);
+ showMenu(x, y);
+ return TRUE;
}
void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index)
@@ -286,13 +286,23 @@ void LLTeleportHistoryFlatItem::onProfileBtnClick()
LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
}
+void LLTeleportHistoryFlatItem::showMenu(S32 x, S32 y)
+{
+ mMenu->setButtonRect(this);
+ mMenu->buildDrawLabels();
+ mMenu->arrangeAndClear();
+ mMenu->updateParent(LLMenuGL::sMenuContainer);
+
+ LLMenuGL::showPopup(this, mMenu, x, y);
+}
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
LLTeleportHistoryFlatItem*
LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem (
- LLTeleportHistoryPanel::ContextMenu *context_menu,
+ LLToggleableMenu *menu,
const LLTeleportHistoryPersistentItem& persistent_item,
const S32 cur_item_index,
const std::string &hl)
@@ -321,7 +331,7 @@ LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem (
if ( !item )
{
item = new LLTeleportHistoryFlatItem(cur_item_index,
- context_menu,
+ menu,
persistent_item.mTitle,
persistent_item.mDate,
hl);
@@ -365,74 +375,6 @@ void LLTeleportHistoryFlatItemStorage::purge()
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-LLTeleportHistoryPanel::ContextMenu::ContextMenu() :
- mMenu(NULL), mIndex(0)
-{
-}
-
-void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y)
-{
- if (mMenu)
- {
- //preventing parent (menu holder) from deleting already "dead" context menus on exit
- LLView* parent = mMenu->getParent();
- if (parent)
- {
- parent->removeChild(mMenu);
- }
- delete mMenu;
- }
-
- mIndex = index;
- mMenu = createMenu();
-
- mMenu->show(x, y);
- LLMenuGL::showPopup(spawning_view, mMenu, x, y);
-}
-
-LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
-{
- // set up the callbacks for all of the avatar menu items
- // (N.B. callbacks don't take const refs as mID is local scope)
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
- registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
- registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this));
-
- // create the context menu from the XUI
- llassert(LLMenuGL::sMenuContainer != NULL);
- return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
- "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onTeleport()
-{
- confirmTeleport(mIndex);
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onInfo()
-{
- LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
-}
-
-//static
-void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
-{
- LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size());
-
- LLSD args;
- args["SLURL"] = slurl;
-
- LLNotificationsUtil::add("CopySLURL", args);
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard()
-{
- LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
- LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
- boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1));
-}
// Not yet implemented; need to remove buildPanel() from constructor when we switch
//static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -446,7 +388,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
mAccordionTabMenu(NULL),
mLastSelectedFlatlList(NULL),
mLastSelectedItemIndex(-1),
- mMenuGearButton(NULL)
+ mGearItemMenu(NULL),
+ mSortingMenu(NULL)
{
buildFromFile( "panel_teleport_history.xml");
}
@@ -454,12 +397,19 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
{
LLTeleportHistoryFlatItemStorage::instance().purge();
- if (mGearMenuHandle.get()) mGearMenuHandle.get()->die();
mTeleportHistoryChangedConnection.disconnect();
}
BOOL LLTeleportHistoryPanel::postBuild()
{
+ mCommitCallbackRegistrar.add("TeleportHistory.GearMenu.Action", boost::bind(&LLTeleportHistoryPanel::onGearMenuAction, this, _2));
+ mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2));
+
+ // init menus before list, since menus are passed to list
+ mGearItemMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_item.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mGearItemMenu->setAlwaysShowMenu(TRUE); // all items can be disabled if nothing is selected, show anyway
+ mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
mTeleportHistory = LLTeleportHistoryStorage::getInstance();
if (mTeleportHistory)
{
@@ -511,22 +461,6 @@ BOOL LLTeleportHistoryPanel::postBuild()
}
}
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this));
- registrar.add("TeleportHistory.CollapseAllFolders", boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders, this));
- registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this));
- mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2));
-
- mMenuGearButton = getChild<LLMenuButton>("gear_btn");
-
- LLToggleableMenu* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());;
- if(gear_menu)
- {
- mGearMenuHandle = gear_menu->getHandle();
- mMenuGearButton->setMenu(gear_menu);
- }
-
return TRUE;
}
@@ -600,6 +534,12 @@ void LLTeleportHistoryPanel::onTeleport()
confirmTeleport(itemp->getIndex());
}
+// virtual
+void LLTeleportHistoryPanel::onRemoveSelected()
+{
+ LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2));
+}
+
/*
// virtual
void LLTeleportHistoryPanel::onCopySLURL()
@@ -630,19 +570,28 @@ void LLTeleportHistoryPanel::updateVerbs()
if (!isTabVisible())
return;
- if (!mLastSelectedFlatlList)
+ if (sRemoveBtn)
{
- mTeleportBtn->setEnabled(false);
- mShowProfile->setEnabled(false);
- mShowOnMapBtn->setEnabled(false);
- return;
+ sRemoveBtn->setEnabled(true);
}
+}
- LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getSelectionMenu()
+{
+ return mGearItemMenu;
+}
+
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getSortingMenu()
+{
+ return mSortingMenu;
+}
- mTeleportBtn->setEnabled(NULL != itemp);
- mShowProfile->setEnabled(NULL != itemp);
- mShowOnMapBtn->setEnabled(NULL != itemp);
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getCreateMenu()
+{
+ return NULL;
}
void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date)
@@ -778,7 +727,7 @@ void LLTeleportHistoryPanel::refresh()
{
LLTeleportHistoryFlatItem* item =
LLTeleportHistoryFlatItemStorage::instance()
- .getFlatItemForPersistentItem(&mContextMenu,
+ .getFlatItemForPersistentItem(mGearItemMenu,
items[mCurrentItem],
mCurrentItem,
filter_string);
@@ -847,7 +796,7 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)
const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems();
LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance()
- .getFlatItemForPersistentItem(&mContextMenu,
+ .getFlatItemForPersistentItem(mGearItemMenu,
history_items[history_items.size() - 1], // Most recent item, it was added instead of removed
history_items.size(), // index will be decremented inside loop below
sFilterSubString);
@@ -1019,38 +968,6 @@ void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)
mHistoryAccordion->arrange();
}
-void LLTeleportHistoryPanel::onExpandAllFolders()
-{
- S32 tabs_cnt = mItemContainers.size();
-
- for (S32 n = 0; n < tabs_cnt; n++)
- {
- mItemContainers.at(n)->setDisplayChildren(true);
- }
- mHistoryAccordion->arrange();
-}
-
-void LLTeleportHistoryPanel::onCollapseAllFolders()
-{
- S32 tabs_cnt = mItemContainers.size();
-
- for (S32 n = 0; n < tabs_cnt; n++)
- {
- mItemContainers.at(n)->setDisplayChildren(false);
- }
- mHistoryAccordion->arrange();
-
- if (mLastSelectedFlatlList)
- {
- mLastSelectedFlatlList->resetSelection();
- }
-}
-
-void LLTeleportHistoryPanel::onClearTeleportHistory()
-{
- LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2));
-}
-
bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response)
{
@@ -1082,45 +999,137 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa
return NULL;
}
-bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
+void LLTeleportHistoryPanel::gotSLURLCallback(const std::string& slurl)
{
- S32 tabs_cnt = mItemContainers.size();
-
- bool has_expanded_tabs = false;
- bool has_collapsed_tabs = false;
-
- for (S32 n = 0; n < tabs_cnt; n++)
- {
- LLAccordionCtrlTab* tab = mItemContainers.at(n);
- if (!tab->getVisible())
- continue;
-
- if (tab->getDisplayChildren())
- {
- has_expanded_tabs = true;
- }
- else
- {
- has_collapsed_tabs = true;
- }
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl), 0, slurl.size());
- if (has_expanded_tabs && has_collapsed_tabs)
- {
- break;
- }
- }
+ LLSD args;
+ args["SLURL"] = slurl;
- std::string command_name = userdata.asString();
+ LLNotificationsUtil::add("CopySLURL", args);
+}
- if (has_expanded_tabs && command_name == "collapse_all")
- {
- return true;
- }
+void LLTeleportHistoryPanel::onGearMenuAction(const LLSD& userdata)
+{
+ std::string command_name = userdata.asString();
+
+ if ("expand_all" == command_name)
+ {
+ S32 tabs_cnt = mItemContainers.size();
+
+ for (S32 n = 0; n < tabs_cnt; n++)
+ {
+ mItemContainers.at(n)->setDisplayChildren(true);
+ }
+ mHistoryAccordion->arrange();
+ }
+ else if ("collapse_all" == command_name)
+ {
+ S32 tabs_cnt = mItemContainers.size();
+
+ for (S32 n = 0; n < tabs_cnt; n++)
+ {
+ mItemContainers.at(n)->setDisplayChildren(false);
+ }
+ mHistoryAccordion->arrange();
+
+ if (mLastSelectedFlatlList)
+ {
+ mLastSelectedFlatlList->resetSelection();
+ }
+ }
+
+ S32 index = -1;
+ if (mLastSelectedFlatlList)
+ {
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+ if (itemp)
+ {
+ index = itemp->getIndex();
+ }
+ }
+
+ if ("teleport" == command_name)
+ {
+ confirmTeleport(index);
+ }
+ else if ("view" == command_name)
+ {
+ LLTeleportHistoryFlatItem::showPlaceInfoPanel(index);
+ }
+ else if ("show_on_map" == command_name)
+ {
+ LLTeleportHistoryStorage::getInstance()->showItemOnMap(index);
+ }
+ else if ("copy_slurl" == command_name)
+ {
+ LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos;
+ LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
+ boost::bind(&LLTeleportHistoryPanel::gotSLURLCallback, _1));
+ }
+}
- if (has_collapsed_tabs && command_name == "expand_all")
- {
- return true;
- }
+bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
+{
+ std::string command_name = userdata.asString();
+
+ if (command_name == "collapse_all"
+ || command_name == "expand_all")
+ {
+ S32 tabs_cnt = mItemContainers.size();
+
+ bool has_expanded_tabs = false;
+ bool has_collapsed_tabs = false;
+
+ for (S32 n = 0; n < tabs_cnt; n++)
+ {
+ LLAccordionCtrlTab* tab = mItemContainers.at(n);
+ if (!tab->getVisible())
+ continue;
+
+ if (tab->getDisplayChildren())
+ {
+ has_expanded_tabs = true;
+ }
+ else
+ {
+ has_collapsed_tabs = true;
+ }
+
+ if (has_expanded_tabs && has_collapsed_tabs)
+ {
+ break;
+ }
+ }
+
+ if (command_name == "collapse_all")
+ {
+ return has_expanded_tabs;
+ }
+
+ if (command_name == "expand_all")
+ {
+ return has_collapsed_tabs;
+ }
+ }
+
+ if (command_name == "clear_history")
+ {
+ return mTeleportHistory->getItems().size() > 0;
+ }
+
+ if ("teleport" == command_name
+ || "view" == command_name
+ || "show_on_map" == command_name
+ || "copy_slurl" == command_name)
+ {
+ if (!mLastSelectedFlatlList)
+ {
+ return false;
+ }
+ LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+ return itemp != NULL;
+ }
return false;
}
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index b88861c5c6..058fee0170 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -43,38 +43,26 @@ class LLMenuButton;
class LLTeleportHistoryPanel : public LLPanelPlacesTab
{
public:
- // *TODO: derive from LLListContextMenu?
- class ContextMenu
- {
- public:
- ContextMenu();
- void show(LLView* spawning_view, S32 index, S32 x, S32 y);
-
- private:
- LLContextMenu* createMenu();
- void onTeleport();
- void onInfo();
- void onCopyToClipboard();
-
- static void gotSLURLCallback(const std::string& slurl);
-
- LLContextMenu* mMenu;
- S32 mIndex;
- };
-
LLTeleportHistoryPanel();
virtual ~LLTeleportHistoryPanel();
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void draw();
+ BOOL postBuild() override;
+ void draw() override;
- /*virtual*/ void onSearchEdit(const std::string& string);
- /*virtual*/ void onShowOnMap();
- /*virtual*/ void onShowProfile();
- /*virtual*/ void onTeleport();
- ///*virtual*/ void onCopySLURL();
- /*virtual*/ void updateVerbs();
- /*virtual*/ bool isSingleItemSelected();
+ void onSearchEdit(const std::string& string) override;
+ void onShowOnMap() override;
+ void onShowProfile() override;
+ void onTeleport() override;
+ ///*virtual*/ void onCopySLURL();
+ void onRemoveSelected() override;
+ void updateVerbs() override;
+ bool isSingleItemSelected() override;
+
+ LLToggleableMenu* getSelectionMenu() override;
+ LLToggleableMenu* getSortingMenu() override;
+ LLToggleableMenu* getCreateMenu() override;
+
+ bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override { return false; }
private:
@@ -88,13 +76,15 @@ private:
void onClearTeleportHistory();
bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response);
- void refresh();
+ void refresh() override;
void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date);
void onTeleportHistoryChange(S32 removed_index);
void replaceItem(S32 removed_index);
void showTeleportHistory();
void handleItemSelect(LLFlatListView* );
LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
+ static void gotSLURLCallback(const std::string& slurl);
+ void onGearMenuAction(const LLSD& userdata);
bool isActionEnabled(const LLSD& userdata) const;
void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
@@ -115,10 +105,10 @@ private:
typedef std::vector<LLAccordionCtrlTab*> item_containers_t;
item_containers_t mItemContainers;
- ContextMenu mContextMenu;
LLContextMenu* mAccordionTabMenu;
- LLHandle<LLView> mGearMenuHandle;
- LLMenuButton* mMenuGearButton;
+
+ LLToggleableMenu* mGearItemMenu;
+ LLToggleableMenu* mSortingMenu;
boost::signals2::connection mTeleportHistoryChangedConnection;
};
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 109013498e..0723a78704 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -31,6 +31,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "llclipboard.h"
+#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "lllandmarkactions.h"
#include "lllocationinputctrl.h"
@@ -456,7 +457,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item)
if(landmark == NULL)
{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+ LLFloaterReg::showInstance("add_landmark");
}
else
{
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 735eaa423d..05d9346f89 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -31,7 +31,6 @@
// linden library includes
#include "llclickaction.h"
-#include "lleconomy.h"
#include "llerror.h"
#include "llfontgl.h"
#include "llflexibleobject.h"
@@ -82,8 +81,11 @@
#include <boost/bind.hpp>
-// "Features" Tab
+const F32 DEFAULT_GRAVITY_MULTIPLIER = 1.f;
+const F32 DEFAULT_DENSITY = 1000.f;
+
+// "Features" Tab
BOOL LLPanelVolume::postBuild()
{
// Flexible Objects Parameters
@@ -298,7 +300,7 @@ void LLPanelVolume::getState( )
{
LightColorSwatch->setEnabled( TRUE );
LightColorSwatch->setValid( TRUE );
- LightColorSwatch->set(volobjp->getLightBaseColor());
+ LightColorSwatch->set(volobjp->getLightSRGBBaseColor());
}
LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
@@ -326,7 +328,7 @@ void LLPanelVolume::getState( )
getChild<LLUICtrl>("Light Focus")->setValue(params.mV[1]);
getChild<LLUICtrl>("Light Ambiance")->setValue(params.mV[2]);
- mLightSavedColor = volobjp->getLightColor();
+ mLightSavedColor = volobjp->getLightSRGBBaseColor();
}
else
{
@@ -583,7 +585,7 @@ void LLPanelVolume::refresh()
mRootObject = NULL;
}
- BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
+ BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
getChildView("Light FOV")->setVisible( visible);
getChildView("Light Focus")->setVisible( visible);
@@ -805,7 +807,7 @@ void LLPanelVolume::onLightSelectColor(const LLSD& data)
{
LLColor4 clr = LightColorSwatch->get();
LLColor3 clr3( clr );
- volobjp->setLightColor(clr3);
+ volobjp->setLightSRGBColor(clr3);
mLightSavedColor = clr;
}
}
@@ -830,7 +832,7 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data)
// static
void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
- //LLPanelObject* self = (LLPanelObject*) userdata;
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
LLComboBox* box = (LLComboBox*) ctrl;
if (box)
@@ -841,6 +843,19 @@ void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
if (material_name != LEGACY_FULLBRIGHT_DESC)
{
U8 material_code = LLMaterialTable::basic.getMCode(material_name);
+ if (self)
+ {
+ LLViewerObject* objectp = self->mObject;
+ if (objectp)
+ {
+ objectp->setPhysicsGravity(DEFAULT_GRAVITY_MULTIPLIER);
+ objectp->setPhysicsFriction(LLMaterialTable::basic.getFriction(material_code));
+ //currently density is always set to 1000 serverside regardless of chosen material,
+ //actual material density should be used here, if this behavior change
+ objectp->setPhysicsDensity(DEFAULT_DENSITY);
+ objectp->setPhysicsRestitution(LLMaterialTable::basic.getRestitution(material_code));
+ }
+ }
LLSelectMgr::getInstance()->selectionSetMaterial(material_code);
}
}
@@ -866,7 +881,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
if(LightColorSwatch)
{
LLColor4 clr = LightColorSwatch->get();
- volobjp->setLightColor(LLColor3(clr));
+ volobjp->setLightSRGBColor(LLColor3(clr));
}
LLTextureCtrl* LightTextureCtrl = self->getChild<LLTextureCtrl>("light texture control");
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index 6792137350..6f11e76a72 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -41,9 +41,6 @@
#include "llfloaterpreference.h"
#include "llsliderctrl.h"
-/* static */ const F32 LLPanelVolumePulldown::sAutoCloseFadeStartTimeSec = 2.0f;
-/* static */ const F32 LLPanelVolumePulldown::sAutoCloseTotalTimeSec = 3.0f;
-
///----------------------------------------------------------------------------
/// Class LLPanelVolumePulldown
///----------------------------------------------------------------------------
@@ -51,8 +48,6 @@
// Default constructor
LLPanelVolumePulldown::LLPanelVolumePulldown()
{
- mHoverTimer.stop();
-
mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
mCommitCallbackRegistrar.add("Vol.SetSounds", boost::bind(&LLPanelVolumePulldown::onClickSetSounds, this));
mCommitCallbackRegistrar.add("Vol.updateMediaAutoPlayCheckbox", boost::bind(&LLPanelVolumePulldown::updateMediaAutoPlayCheckbox, this, _1));
@@ -62,41 +57,7 @@ LLPanelVolumePulldown::LLPanelVolumePulldown()
BOOL LLPanelVolumePulldown::postBuild()
{
- return LLPanel::postBuild();
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.stop();
- LLPanel::onMouseEnter(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onTopLost()
-{
- setVisible(FALSE);
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mHoverTimer.start();
- LLPanel::onMouseLeave(x,y,mask);
-}
-
-/*virtual*/
-void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility )
-{
- if (new_visibility)
- {
- mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
- }
- else
- {
- mHoverTimer.stop();
-
- }
+ return LLPanelPulldown::postBuild();
}
void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data)
@@ -140,7 +101,7 @@ void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
- getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
+ getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}
@@ -150,20 +111,3 @@ void LLPanelVolumePulldown::onClickSetSounds()
// or if sound effects are disabled.
getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
}
-
-//virtual
-void LLPanelVolumePulldown::draw()
-{
- F32 alpha = mHoverTimer.getStarted()
- ? clamp_rescale(mHoverTimer.getElapsedTimeF32(), sAutoCloseFadeStartTimeSec, sAutoCloseTotalTimeSec, 1.f, 0.f)
- : 1.0f;
- LLViewDrawContext context(alpha);
-
- LLPanel::draw();
-
- if (alpha == 0.f)
- {
- setVisible(FALSE);
- }
-}
-
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index 4f23112f50..e907bb0c78 100644
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
@@ -30,19 +30,12 @@
#include "linden_common.h"
-#include "llpanel.h"
+#include "llpanelpulldown.h"
-class LLFrameTimer;
-
-class LLPanelVolumePulldown : public LLPanel
+class LLPanelVolumePulldown : public LLPanelPulldown
{
public:
LLPanelVolumePulldown();
- /*virtual*/ void draw();
- /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ void onTopLost();
- /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
/*virtual*/ BOOL postBuild();
private:
@@ -52,10 +45,6 @@ class LLPanelVolumePulldown : public LLPanel
// "Streaming Music" and "Media" are unchecked. Otherwise enables it.
void updateMediaAutoPlayCheckbox(LLUICtrl* ctrl);
void onAdvancedButtonClick(const LLSD& user_data);
-
- LLFrameTimer mHoverTimer;
- static const F32 sAutoCloseFadeStartTimeSec;
- static const F32 sAutoCloseTotalTimeSec;
};
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 89cb495db9..3347c40687 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -64,7 +64,9 @@ public:
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
- registrar.add("Gear.Edit", boost::bind(&edit_outfit));
+ registrar.add("Gear.TouchAttach", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_attachment_touch));
+ registrar.add("Gear.EditItem", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_item_edit));
+ registrar.add("Gear.EditOutfit", boost::bind(&edit_outfit));
registrar.add("Gear.TakeOff", boost::bind(&LLPanelWearing::onRemoveItem, mPanelWearing));
registrar.add("Gear.Copy", boost::bind(&LLPanelWearing::copyToClipboard, mPanelWearing));
@@ -78,6 +80,16 @@ public:
LLToggleableMenu* getMenu() { return mMenu; }
private:
+ void handleMultiple(std::function<void(const LLUUID& id)> functor)
+ {
+ uuid_vec_t selected_item_ids;
+ mPanelWearing->getSelectedItemsUUIDs(selected_item_ids);
+
+ for (const LLUUID& item_id : selected_item_ids)
+ {
+ functor(item_id);
+ }
+ }
LLToggleableMenu* mMenu;
LLPanelWearing* mPanelWearing;
@@ -92,7 +104,9 @@ protected:
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
+ registrar.add("Wearing.TouchAttach", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
+ registrar.add("Wearing.EditItem", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
+ registrar.add("Wearing.EditOutfit", boost::bind(&edit_outfit));
registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front()));
registrar.add("Wearing.TakeOff",
boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
@@ -138,14 +152,19 @@ protected:
}
// Enable/disable some menu items depending on the selection.
+ bool show_touch = !bp_selected && !clothes_selected && attachments_selected;
+ bool show_edit = bp_selected || clothes_selected || attachments_selected;
bool allow_detach = !bp_selected && !clothes_selected && attachments_selected;
bool allow_take_off = !bp_selected && clothes_selected && !attachments_selected;
+ menu->setItemVisible("touch_attach", show_touch);
+ menu->setItemEnabled("touch_attach", 1 == mUUIDs.size() && enable_attachment_touch(mUUIDs.front()));
+ menu->setItemVisible("edit_item", show_edit);
+ menu->setItemEnabled("edit_item", 1 == mUUIDs.size() && get_is_item_editable(mUUIDs.front()));
menu->setItemVisible("take_off", allow_take_off);
menu->setItemVisible("detach", allow_detach);
- menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);
+ menu->setItemVisible("edit_outfit_separator", show_touch | show_edit | allow_take_off || allow_detach);
menu->setItemVisible("show_original", mUUIDs.size() == 1);
- menu->setItemVisible("edit_item", FALSE);
}
};
@@ -173,12 +192,15 @@ protected:
void updateMenuItemsVisibility(LLContextMenu* menu)
{
+ menu->setItemVisible("touch_attach", TRUE);
+ menu->setItemEnabled("touch_attach", 1 == mUUIDs.size());
+ menu->setItemVisible("edit_item", TRUE);
+ menu->setItemEnabled("edit_item", 1 == mUUIDs.size());
menu->setItemVisible("take_off", FALSE);
menu->setItemVisible("detach", TRUE);
- menu->setItemVisible("edit_outfit_separator", TRUE);
+ menu->setItemVisible("edit_outfit_separator", FALSE);
menu->setItemVisible("show_original", FALSE);
- menu->setItemVisible("edit_item", TRUE);
- menu->setItemVisible("edit", FALSE);
+ menu->setItemVisible("edit_outfit", FALSE);
}
LLPanelWearing* mPanelWearing;
@@ -350,6 +372,18 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
}
}
+ uuid_vec_t selected_uuids;
+ getSelectedItemsUUIDs(selected_uuids);
+
+ if (command_name == "touch_attach")
+ {
+ return (1 == selected_uuids.size()) && (enable_attachment_touch(selected_uuids.front()));
+ }
+ else if (command_name == "edit_item")
+ {
+ return (1 == selected_uuids.size()) && (get_is_item_editable(selected_uuids.front()));
+ }
+
return false;
}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index ee6893907e..94d20828ec 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -259,11 +259,7 @@ LLParticipantList::~LLParticipantList()
*/
void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
{
- LLConversationItemParticipant* participant = findParticipant(participant_id);
- if (participant)
- {
- removeParticipant(participant);
- }
+ removeParticipant(participant_id);
// re-add avaline caller with a correct class instance.
addAvatarIDExceptAgent(participant_id);
}
@@ -397,6 +393,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
// Add the participant model to the session's children list
+ // This will post "add_participant" event
addParticipant(participant);
adjustParticipant(avatar_id);
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 5eadd65884..1c14acd843 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -43,9 +43,8 @@ static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_invent
static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER;
LLPlacesInventoryPanel::LLPlacesInventoryPanel(const Params& p) :
- LLInventoryPanel(p),
+ LLAssetFilteredInventoryPanel(p),
mSavedFolderState(NULL)
-
{
mInvFVBridgeBuilder = &PLACES_INVENTORY_BUILDER;
mSavedFolderState = new LLSaveFolderState();
@@ -78,6 +77,7 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
p.view_model = &mInventoryViewModel;
p.use_label_suffix = mParams.use_label_suffix;
p.allow_multiselect = mAllowMultiSelect;
+ p.allow_drag = mAllowDrag;
p.show_empty_message = mShowEmptyMessage;
p.show_item_link_overlays = mShowItemLinkOverlays;
p.root = NULL;
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 27d9b83bd1..5629438415 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -32,14 +32,16 @@
class LLLandmarksPanel;
class LLFolderView;
-class LLPlacesInventoryPanel : public LLInventoryPanel
+class LLPlacesInventoryPanel : public LLAssetFilteredInventoryPanel
{
public:
struct Params
- : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+ : public LLInitParam::Block<Params, LLAssetFilteredInventoryPanel::Params>
{
Params()
- {}
+ {
+ filter_asset_type = "landmark";
+ }
};
LLPlacesInventoryPanel(const Params& p);
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index df93572508..c267c3c699 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -39,6 +39,8 @@
#include "llfloaterpreference.h"
#include "llfloaterreg.h"
#include "llfeaturemanager.h"
+#include "llagentcamera.h"
+#include "llfile.h"
LLPresetsManager::LLPresetsManager()
{
@@ -46,6 +48,12 @@ LLPresetsManager::LLPresetsManager()
LLPresetsManager::~LLPresetsManager()
{
+ mCameraChangedSignal.disconnect();
+}
+
+void LLPresetsManager::triggerChangeCameraSignal()
+{
+ mPresetListChangeCameraSignal();
}
void LLPresetsManager::triggerChangeSignal()
@@ -53,41 +61,92 @@ void LLPresetsManager::triggerChangeSignal()
mPresetListChangeSignal();
}
-void LLPresetsManager::createMissingDefault()
+void LLPresetsManager::createMissingDefault(const std::string& subdirectory)
{
if(gDirUtilp->getLindenUserDir().empty())
{
return;
}
- std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, PRESETS_GRAPHIC, PRESETS_DEFAULT + ".xml");
+
+ if (PRESETS_CAMERA == subdirectory)
+ {
+ createCameraDefaultPresets();
+ return;
+ }
+
+ std::string default_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
+ subdirectory, PRESETS_DEFAULT + ".xml");
if (!gDirUtilp->fileExists(default_file))
{
LL_INFOS() << "No default preset found -- creating one at " << default_file << LL_ENDL;
- // Write current graphic settings as the default
- savePreset(PRESETS_GRAPHIC, PRESETS_DEFAULT, true);
+ // Write current settings as the default
+ savePreset(subdirectory, PRESETS_DEFAULT, true);
+ }
+ else
+ {
+ LL_DEBUGS() << "default preset exists; no-op" << LL_ENDL;
+ }
+}
+
+void LLPresetsManager::createCameraDefaultPresets()
+{
+ bool is_default_created = createDefaultCameraPreset(PRESETS_REAR_VIEW);
+ is_default_created |= createDefaultCameraPreset(PRESETS_FRONT_VIEW);
+ is_default_created |= createDefaultCameraPreset(PRESETS_SIDE_VIEW);
+
+ if (is_default_created)
+ {
+ triggerChangeCameraSignal();
+ }
+}
+
+void LLPresetsManager::startWatching(const std::string& subdirectory)
+{
+ if (PRESETS_CAMERA == subdirectory)
+ {
+ std::vector<std::string> name_list;
+ getControlNames(name_list);
+
+ for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
+ {
+ std::string ctrl_name = *it;
+ if (gSavedSettings.controlExists(ctrl_name))
+ {
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(ctrl_name);
+ if (cntrl_ptr.isNull())
+ {
+ LL_WARNS("Init") << "Unable to set signal on global setting '" << ctrl_name
+ << "'" << LL_ENDL;
+ }
+ else
+ {
+ mCameraChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&settingChanged));
+ }
+ }
+ }
}
- else
- {
- LL_DEBUGS() << "default preset exists; no-op" << LL_ENDL;
- }
}
std::string LLPresetsManager::getPresetsDir(const std::string& subdirectory)
{
std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR);
- std::string full_path;
LLFile::mkdir(presets_path);
- full_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
- LLFile::mkdir(full_path);
+ std::string dest_path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR, subdirectory);
+ if (!gDirUtilp->fileExists(dest_path))
+ LLFile::mkdir(dest_path);
- return full_path;
+ return dest_path;
}
-void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option)
+void LLPresetsManager::loadPresetNamesFromDir(const std::string& subdirectory, preset_name_list_t& presets, EDefaultOptions default_option)
{
+ bool IS_CAMERA = (PRESETS_CAMERA == subdirectory);
+ bool IS_GRAPHIC = (PRESETS_GRAPHIC == subdirectory);
+
+ std::string dir = LLPresetsManager::getInstance()->getPresetsDir(subdirectory);
LL_INFOS("AppInit") << "Loading list of preset names from " << dir << LL_ENDL;
mPresetNames.clear();
@@ -103,16 +162,33 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
{
std::string path = gDirUtilp->add(dir, file);
std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));
- LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL;
+ LL_DEBUGS() << " Found preset '" << name << "'" << LL_ENDL;
- if (PRESETS_DEFAULT != name)
+ if (IS_CAMERA)
{
+ if (isTemplateCameraPreset(name))
+ {
+ continue;
+ }
+ if ((default_option == DEFAULT_HIDE) || (default_option == DEFAULT_BOTTOM))
+ {
+ if (isDefaultCameraPreset(name))
+ {
+ continue;
+ }
+ }
mPresetNames.push_back(name);
}
- else
+ if (IS_GRAPHIC)
{
- switch (default_option)
+ if (PRESETS_DEFAULT != name)
{
+ mPresetNames.push_back(name);
+ }
+ else
+ {
+ switch (default_option)
+ {
case DEFAULT_SHOW:
mPresetNames.push_back(LLTrans::getString(PRESETS_DEFAULT));
break;
@@ -124,16 +200,77 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
case DEFAULT_HIDE:
default:
break;
+ }
}
}
}
}
+ if (IS_CAMERA)
+ {
+ mPresetNames.sort(LLStringUtil::precedesDict);
+ if (default_option == DEFAULT_BOTTOM)
+ {
+ mPresetNames.push_back(PRESETS_FRONT_VIEW);
+ mPresetNames.push_back(PRESETS_REAR_VIEW);
+ mPresetNames.push_back(PRESETS_SIDE_VIEW);
+ }
+ }
+
presets = mPresetNames;
}
+bool LLPresetsManager::mCameraDirty = false;
+bool LLPresetsManager::mIgnoreChangedSignal = false;
+
+void LLPresetsManager::setCameraDirty(bool dirty)
+{
+ mCameraDirty = dirty;
+}
+
+bool LLPresetsManager::isCameraDirty()
+{
+ return mCameraDirty;
+}
+
+void LLPresetsManager::settingChanged()
+{
+ setCameraDirty(true);
+
+ static LLCachedControl<std::string> preset_camera_active(gSavedSettings, "PresetCameraActive", "");
+ std::string preset_name = preset_camera_active;
+ if (!preset_name.empty() && !mIgnoreChangedSignal)
+ {
+ gSavedSettings.setString("PresetCameraActive", "");
+
+ // Hack call because this is a static routine
+ LLPresetsManager::getInstance()->triggerChangeCameraSignal();
+ }
+}
+
+void LLPresetsManager::getControlNames(std::vector<std::string>& names)
+{
+ const std::vector<std::string> camera_controls = boost::assign::list_of
+ // From panel_preferences_move.xml
+ ("CameraAngle")
+ ("CameraOffsetScale")
+ ("EditCameraMovement")
+ ("AppearanceCameraMovement")
+ // From llagentcamera.cpp
+ ("CameraOffsetBuild")
+ ("TrackFocusObject")
+ ("CameraOffsetRearView")
+ ("FocusOffsetRearView")
+ ("AvatarSitRotation")
+ ;
+ names = camera_controls;
+}
+
bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string name, bool createDefault)
{
+ bool IS_CAMERA = (PRESETS_CAMERA == subdirectory);
+ bool IS_GRAPHIC = (PRESETS_GRAPHIC == subdirectory);
+
if (LLTrans::getString(PRESETS_DEFAULT) == name)
{
name = PRESETS_DEFAULT;
@@ -144,126 +281,174 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
return false;
}
+ if (isTemplateCameraPreset(name))
+ {
+ LL_WARNS() << "Should not overwrite template presets" << LL_ENDL;
+ return false;
+ }
+
bool saved = false;
std::vector<std::string> name_list;
- if(PRESETS_GRAPHIC == subdirectory)
+ if (IS_GRAPHIC)
{
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
if (instance && !createDefault)
{
- gSavedSettings.setString("PresetGraphicActive", name);
+ gSavedSettings.setString("PresetGraphicActive", name);
instance->getControlNames(name_list);
- LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL;
+ LL_DEBUGS() << "saving preset '" << name << "'; " << name_list.size() << " names" << LL_ENDL;
name_list.push_back("PresetGraphicActive");
}
- else
+ else
{
- LL_WARNS() << "preferences floater instance not found" << LL_ENDL;
- }
+ LL_WARNS("Presets") << "preferences floater instance not found" << LL_ENDL;
+ }
}
- else if(PRESETS_CAMERA == subdirectory)
+ else if (IS_CAMERA)
{
name_list.clear();
- name_list.push_back("Placeholder");
+ getControlNames(name_list);
+ name_list.push_back("PresetCameraActive");
}
- else
- {
- LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL;
- }
-
- if (name_list.size() > 1 // if the active preset name is the only thing in the list, don't save the list
- || (createDefault && name == PRESETS_DEFAULT && subdirectory == PRESETS_GRAPHIC)) // or create a default graphics preset from hw recommended settings
- {
- // make an empty llsd
- LLSD paramsData(LLSD::emptyMap());
+ else
+ {
+ LL_ERRS() << "Invalid presets directory '" << subdirectory << "'" << LL_ENDL;
+ }
+
+ // make an empty llsd
+ LLSD paramsData(LLSD::emptyMap());
- if (createDefault)
- {
- paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap();
- if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0)
- {
- // use the recommended setting as an initial one (MAINT-6435)
- gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger());
- }
- }
- else
- {
- for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
- {
- std::string ctrl_name = *it;
- LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
- std::string comment = ctrl->getComment();
- std::string type = LLControlGroup::typeEnumToString(ctrl->type());
- LLSD value = ctrl->getValue();
-
- paramsData[ctrl_name]["Comment"] = comment;
- paramsData[ctrl_name]["Persist"] = 1;
- paramsData[ctrl_name]["Type"] = type;
- paramsData[ctrl_name]["Value"] = value;
- }
- }
-
- std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
-
- // write to file
- llofstream presetsXML(pathName.c_str());
- if (presetsXML.is_open())
- {
-
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
- presetsXML.close();
- saved = true;
+ // Create a default graphics preset from hw recommended settings
+ if (IS_GRAPHIC && createDefault && name == PRESETS_DEFAULT)
+ {
+ paramsData = LLFeatureManager::getInstance()->getRecommendedSettingsMap();
+ if (gSavedSettings.getU32("RenderAvatarMaxComplexity") == 0)
+ {
+ // use the recommended setting as an initial one (MAINT-6435)
+ gSavedSettings.setU32("RenderAvatarMaxComplexity", paramsData["RenderAvatarMaxComplexity"]["Value"].asInteger());
+ }
+ }
+ else
+ {
+ ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
+ bool new_camera_offsets = false;
+ if (IS_CAMERA)
+ {
+ if (isDefaultCameraPreset(name))
+ {
+ if (PRESETS_REAR_VIEW == name)
+ {
+ new_camera_preset = CAMERA_PRESET_REAR_VIEW;
+ }
+ else if (PRESETS_SIDE_VIEW == name)
+ {
+ new_camera_preset = CAMERA_PRESET_GROUP_VIEW;
+ }
+ else if (PRESETS_FRONT_VIEW == name)
+ {
+ new_camera_preset = CAMERA_PRESET_FRONT_VIEW;
+ }
+ }
+ else
+ {
+ 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)
+ {
+ std::string ctrl_name = *it;
+
+ LLControlVariable* ctrl = gSavedSettings.getControl(ctrl_name).get();
+ if (ctrl)
+ {
+ std::string comment = ctrl->getComment();
+ std::string type = LLControlGroup::typeEnumToString(ctrl->type());
+ LLSD value = ctrl->getValue();
+
+ paramsData[ctrl_name]["Comment"] = comment;
+ paramsData[ctrl_name]["Persist"] = 1;
+ paramsData[ctrl_name]["Type"] = type;
+ paramsData[ctrl_name]["Value"] = value;
+ }
+ }
+ if (IS_CAMERA)
+ {
+ gSavedSettings.setU32("CameraPresetType", new_camera_preset);
+ }
+ }
+
+ std::string pathName(getPresetsDir(subdirectory) + gDirUtilp->getDirDelimiter() + LLURI::escape(name) + ".xml");
+
+ // If the active preset name is the only thing in the list, don't save the list
+ if (paramsData.size() > 1)
+ {
+ // write to file
+ llofstream presetsXML(pathName.c_str());
+ if (presetsXML.is_open())
+ {
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
+ presetsXML.close();
+ saved = true;
- LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL;
-
- if (!createDefault)
- {
- gSavedSettings.setString("PresetGraphicActive", name);
- // signal interested parties
- triggerChangeSignal();
- }
- }
- else
- {
- LL_WARNS("Presets") << "Cannot open for output preset file " << pathName << LL_ENDL;
- }
- }
+ LL_DEBUGS() << "saved preset '" << name << "'; " << paramsData.size() << " parameters" << LL_ENDL;
+
+ if (IS_GRAPHIC)
+ {
+ gSavedSettings.setString("PresetGraphicActive", name);
+ // signal interested parties
+ triggerChangeSignal();
+ }
+
+ if (IS_CAMERA)
+ {
+ gSavedSettings.setString("PresetCameraActive", name);
+ setCameraDirty(false);
+ // signal interested parties
+ triggerChangeCameraSignal();
+ }
+ }
+ else
+ {
+ LL_WARNS("Presets") << "Cannot open for output preset file " << pathName << LL_ENDL;
+ }
+ }
else
- {
- LL_INFOS() << "No settings found; preferences floater has not yet been created" << LL_ENDL;
- }
+ {
+ LL_INFOS() << "No settings available to be saved" << LL_ENDL;
+ }
return saved;
}
-void LLPresetsManager::setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option)
+bool LLPresetsManager::setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option)
{
+ bool sts = true;
+
combo->clearRows();
+ combo->setEnabled(TRUE);
- std::string presets_dir = getPresetsDir(subdirectory);
+ std::list<std::string> preset_names;
+ loadPresetNamesFromDir(subdirectory, preset_names, default_option);
- if (!presets_dir.empty())
+ if (preset_names.begin() != preset_names.end())
{
- std::list<std::string> preset_names;
- loadPresetNamesFromDir(presets_dir, preset_names, default_option);
-
- std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive");
-
- if (preset_names.begin() != preset_names.end())
- {
- for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
- {
- const std::string& name = *it;
- combo->add(name, LLSD().with(0, name));
- }
- }
- else
+ for (std::list<std::string>::const_iterator it = preset_names.begin(); it != preset_names.end(); ++it)
{
- combo->setLabel(LLTrans::getString("preset_combo_label"));
+ const std::string& name = *it;
+ combo->add(name, name);
}
}
+ else
+ {
+ combo->setLabel(LLTrans::getString("preset_combo_label"));
+ combo->setEnabled(PRESETS_CAMERA != subdirectory);
+ sts = false;
+ }
+
+ return sts;
}
void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string name)
@@ -277,24 +462,32 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
LL_DEBUGS() << "attempting to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
+ mIgnoreChangedSignal = true;
if(gSavedSettings.loadFromFile(full_path, false, true) > 0)
{
+ mIgnoreChangedSignal = false;
if(PRESETS_GRAPHIC == subdirectory)
{
gSavedSettings.setString("PresetGraphicActive", name);
- }
- LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
- if (instance)
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->refreshEnabledGraphics();
+ }
+ triggerChangeSignal();
+ }
+ if(PRESETS_CAMERA == subdirectory)
{
- instance->refreshEnabledGraphics();
+ gSavedSettings.setString("PresetCameraActive", name);
+ triggerChangeCameraSignal();
}
- triggerChangeSignal();
}
- else
- {
- LL_WARNS() << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
- }
+ else
+ {
+ mIgnoreChangedSignal = false;
+ LL_WARNS("Presets") << "failed to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
+ }
}
bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string name)
@@ -320,17 +513,70 @@ bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string
}
// If you delete the preset that is currently marked as loaded then also indicate that no preset is loaded.
- if (gSavedSettings.getString("PresetGraphicActive") == name)
+ if(PRESETS_GRAPHIC == subdirectory)
{
- gSavedSettings.setString("PresetGraphicActive", "");
+ if (gSavedSettings.getString("PresetGraphicActive") == name)
+ {
+ gSavedSettings.setString("PresetGraphicActive", "");
+ }
+ // signal interested parties
+ triggerChangeSignal();
}
- // signal interested parties
- triggerChangeSignal();
+ if(PRESETS_CAMERA == subdirectory)
+ {
+ if (gSavedSettings.getString("PresetCameraActive") == name)
+ {
+ gSavedSettings.setString("PresetCameraActive", "");
+ }
+ // signal interested parties
+ triggerChangeCameraSignal();
+ }
return sts;
}
+bool LLPresetsManager::isDefaultCameraPreset(std::string preset_name)
+{
+ return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW);
+}
+
+bool LLPresetsManager::isTemplateCameraPreset(std::string preset_name)
+{
+ return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT);
+}
+
+void LLPresetsManager::resetCameraPreset(std::string preset_name)
+{
+ if (isDefaultCameraPreset(preset_name))
+ {
+ createDefaultCameraPreset(preset_name, true);
+
+ if (gSavedSettings.getString("PresetCameraActive") == preset_name)
+ {
+ loadPreset(PRESETS_CAMERA, preset_name);
+ }
+ }
+}
+
+bool LLPresetsManager::createDefaultCameraPreset(std::string preset_name, bool force_reset)
+{
+ std::string preset_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PRESETS_DIR,
+ PRESETS_CAMERA, LLURI::escape(preset_name) + ".xml");
+ if (!gDirUtilp->fileExists(preset_file) || force_reset)
+ {
+ std::string template_name = preset_name.substr(0, preset_name.size() - PRESETS_VIEW_SUFFIX.size());
+ std::string default_template_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, PRESETS_CAMERA, template_name + ".xml");
+ return LLFile::copy(default_template_file, preset_file);
+ }
+ return false;
+}
+
+boost::signals2::connection LLPresetsManager::setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb)
+{
+ return mPresetListChangeCameraSignal.connect(cb);
+}
+
boost::signals2::connection LLPresetsManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
{
return mPresetListChangeSignal.connect(cb);
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index 0014e32267..0de30e9e01 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -33,14 +33,23 @@
#include <map>
static const std::string PRESETS_DEFAULT = "Default";
+static const std::string PRESETS_DEFAULT_UPPER = "DEFAULT";
static const std::string PRESETS_DIR = "presets";
static const std::string PRESETS_GRAPHIC = "graphic";
static const std::string PRESETS_CAMERA = "camera";
+static const std::string PRESETS_REAR = "Rear";
+static const std::string PRESETS_FRONT = "Front";
+static const std::string PRESETS_SIDE = "Side";
+static const std::string PRESETS_VIEW_SUFFIX = " View";
+static const std::string PRESETS_REAR_VIEW = PRESETS_REAR + PRESETS_VIEW_SUFFIX;
+static const std::string PRESETS_FRONT_VIEW = PRESETS_FRONT + PRESETS_VIEW_SUFFIX;
+static const std::string PRESETS_SIDE_VIEW = PRESETS_SIDE + PRESETS_VIEW_SUFFIX;
enum EDefaultOptions
{
DEFAULT_SHOW,
DEFAULT_TOP,
+ DEFAULT_BOTTOM,
DEFAULT_HIDE // Do not display "Default" in a list
};
@@ -54,26 +63,47 @@ public:
typedef std::list<std::string> preset_name_list_t;
typedef boost::signals2::signal<void()> preset_list_signal_t;
- void createMissingDefault();
+ void createMissingDefault(const std::string& subdirectory);
+ void startWatching(const std::string& subdirectory);
+ void triggerChangeCameraSignal();
void triggerChangeSignal();
static std::string getPresetsDir(const std::string& subdirectory);
- void setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option);
- void loadPresetNamesFromDir(const std::string& dir, preset_name_list_t& presets, EDefaultOptions default_option);
+ bool setPresetNamesInComboBox(const std::string& subdirectory, LLComboBox* combo, EDefaultOptions default_option);
+ void loadPresetNamesFromDir(const std::string& subdirectory, preset_name_list_t& presets, EDefaultOptions default_option);
bool savePreset(const std::string& subdirectory, std::string name, bool createDefault = false);
void loadPreset(const std::string& subdirectory, std::string name);
bool deletePreset(const std::string& subdirectory, std::string name);
+ bool isCameraDirty();
+ static void setCameraDirty(bool dirty);
+
+ void createCameraDefaultPresets();
+
+ bool isTemplateCameraPreset(std::string preset_name);
+ bool isDefaultCameraPreset(std::string preset_name);
+ void resetCameraPreset(std::string preset_name);
+ bool createDefaultCameraPreset(std::string preset_name, bool force_reset = false);
// Emitted when a preset gets loaded, deleted, or saved.
+ boost::signals2::connection setPresetListChangeCameraCallback(const preset_list_signal_t::slot_type& cb);
boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
// Emitted when a preset gets loaded or saved.
preset_name_list_t mPresetNames;
+ preset_list_signal_t mPresetListChangeCameraSignal;
preset_list_signal_t mPresetListChangeSignal;
private:
- LOG_CLASS(LLPresetsManager);
+ LOG_CLASS(LLPresetsManager);
+
+ void getControlNames(std::vector<std::string>& names);
+ static void settingChanged();
+
+ boost::signals2::connection mCameraChangedSignal;
+
+ static bool mCameraDirty;
+ static bool mIgnoreChangedSignal;
};
#endif // LL_PRESETSMANAGER_H
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 787bd68e58..18c2fb5452 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -373,11 +373,11 @@ BOOL LLPreviewGesture::postBuild()
mReplaceEditor = edit;
combo = getChild<LLComboBox>( "modifier_combo");
- combo->setCommitCallback(onCommitSetDirty, this);
+ combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this));
mModifierCombo = combo;
combo = getChild<LLComboBox>( "key_combo");
- combo->setCommitCallback(onCommitSetDirty, this);
+ combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this));
mKeyCombo = combo;
list = getChild<LLScrollListCtrl>("library_list");
@@ -937,12 +937,16 @@ void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
break;
}
+ mModifierCombo->setEnabledByValue(CTRL_LABEL, gesture->mKey != KEY_F10);
+
mKeyCombo->setCurrentByIndex(0);
if (gesture->mKey != KEY_NONE)
{
mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey));
}
+ mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), gesture->mMask != MASK_CONTROL);
+
// Make UI steps for each gesture step
S32 i;
S32 count = gesture->mSteps.size();
@@ -1091,7 +1095,7 @@ void LLPreviewGesture::saveIfNeeded()
const LLViewerRegion* region = gAgent.getRegion();
if (!region)
{
- LL_WARNS() << "Not connected to a region, cannot save notecard." << LL_ENDL;
+ LL_WARNS() << "Not connected to a region, cannot save gesture." << LL_ENDL;
return;
}
std::string agent_url = region->getCapability("UpdateGestureAgentInventory");
@@ -1111,13 +1115,15 @@ void LLPreviewGesture::saveIfNeeded()
refresh();
item->setComplete(true);
- uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_GESTURE, buffer,
- boost::bind(&LLPreviewGesture::finishInventoryUpload, _1, _2)));
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mItemUUID, LLAssetType::AT_GESTURE, buffer,
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD) {
+ LLPreviewGesture::finishInventoryUpload(itemId, newAssetId);
+ });
url = agent_url;
}
else if (!mObjectUUID.isNull() && !task_url.empty())
{
- uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, NULL));
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr);
url = task_url;
}
@@ -1336,6 +1342,17 @@ LLMultiGesture* LLPreviewGesture::createGesture()
}
+void LLPreviewGesture::onCommitKeyorModifier()
+{
+ // SL-14139: ctrl-F10 is currently used to access top menu,
+ // so don't allow to bound gestures to this combination.
+
+ mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), mModifierCombo->getSimple() != CTRL_LABEL);
+ mModifierCombo->setEnabledByValue(CTRL_LABEL, mKeyCombo->getSimple() != LLKeyboard::stringFromKey(KEY_F10));
+ mDirty = TRUE;
+ refresh();
+}
+
// static
void LLPreviewGesture::updateLabel(LLScrollListItem* item)
{
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index 3ba4f56295..ffcada4cc2 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -103,6 +103,8 @@ protected:
LLScrollListItem* addStep(const enum EStepType step_type);
void onVisibilityChanged ( const LLSD& new_visibility );
+
+ void onCommitKeyorModifier();
static std::string getLabel(std::vector<std::string> labels);
static void updateLabel(LLScrollListItem* item);
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 1533a27469..1b60610668 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -307,6 +307,7 @@ void LLPreviewNotecard::loadAsset()
{
editor->setEnabled(FALSE);
getChildView("lock")->setVisible( TRUE);
+ getChildView("Edit")->setEnabled(FALSE);
}
if((allow_modify || is_owner) && !source_library)
@@ -367,6 +368,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
previewEditor->makePristine();
BOOL modifiable = preview->canModify(preview->mObjectID, preview->getItem());
preview->setEnabled(modifiable);
+ preview->syncExternal();
preview->mAssetStatus = PREVIEW_ASSET_LOADED;
}
else
@@ -503,10 +505,6 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
}
editor->makePristine();
- if (sync)
- {
- syncExternal();
- }
const LLInventoryItem* item = getItem();
// save it out to database
if (item)
@@ -527,14 +525,19 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
if (mObjectUUID.isNull() && !agent_url.empty())
{
- uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_NOTECARD, buffer,
- boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _2, _3)));
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mItemUUID, LLAssetType::AT_NOTECARD, buffer,
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) {
+ LLPreviewNotecard::finishInventoryUpload(itemId, newAssetId, newItemId);
+ });
url = agent_url;
}
else if (!mObjectUUID.isNull() && !task_url.empty())
{
- uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,
- boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID)));
+ LLUUID object_uuid(mObjectUUID);
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,
+ [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) {
+ LLPreviewNotecard::finishTaskUpload(itemId, newAssetId, object_uuid);
+ });
url = task_url;
}
@@ -755,6 +758,7 @@ void LLPreviewNotecard::openInExternalEditor()
// Start watching file changes.
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1));
+ mLiveFile->ignoreNextUpdate();
mLiveFile->addToEventTimer();
// Open it in external editor.
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index d177384b5a..4c539ded38 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -33,7 +33,6 @@
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "lldir.h"
-#include "llenvmanager.h"
#include "llexternaleditor.h"
#include "llfilepicker.h"
#include "llfloaterreg.h"
@@ -545,9 +544,6 @@ void LLScriptEdCore::initMenu()
menuItem = getChild<LLMenuItemCallGL>("Go to line...");
menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
- menuItem = getChild<LLMenuItemCallGL>("Help...");
- menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
-
menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
@@ -737,7 +733,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
}
if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME))
{
- std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+ // Use Wtext since segment's start/end are made for wstring and will
+ // result in a shift for case of multi-byte symbols inside std::string.
+ LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+ std::string help_string = wstring_to_utf8str(segment_text);
setHelpPage(help_string);
mLiveHelpTimer.stop();
}
@@ -883,11 +882,6 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
return false;
}
-void LLScriptEdCore::onBtnHelp()
-{
- LLUI::getInstance()->mHelpImpl->showTopic(HELP_LSL_PORTAL_TOPIC);
-}
-
void LLScriptEdCore::onBtnDynamicHelp()
{
LLFloater* live_help_floater = mLiveHelpHandle.get();
@@ -1693,9 +1687,11 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
if (!url.empty())
{
std::string buffer(mScriptEd->mEditor->getText());
- LLBufferedAssetUploadInfo::invnUploadFinish_f proc = boost::bind(&LLPreviewLSL::finishedLSLUpload, _1, _4);
- LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mItemUUID, buffer, proc));
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLScriptAssetUpload>(mItemUUID, buffer,
+ [](LLUUID itemId, LLUUID, LLUUID, LLSD response) {
+ LLPreviewLSL::finishedLSLUpload(itemId, response);
+ }));
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
@@ -2243,11 +2239,13 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)
if (!url.empty())
{
std::string buffer(mScriptEd->mEditor->getText());
- LLBufferedAssetUploadInfo::taskUploadFinish_f proc = boost::bind(&LLLiveLSLEditor::finishLSLUpload, _1, _2, _3, _4, isRunning);
- LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mObjectUUID, mItemUUID,
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLScriptAssetUpload>(mObjectUUID, mItemUUID,
monoChecked() ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2,
- isRunning, mScriptEd->getAssociatedExperience(), buffer, proc));
+ isRunning, mScriptEd->getAssociatedExperience(), buffer,
+ [isRunning](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) {
+ LLLiveLSLEditor::finishLSLUpload(itemId, taskId, newAssetId, response, isRunning);
+ }));
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 74e4c00d43..3cf22a0e6e 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -144,7 +144,6 @@ public:
void setItemRemoved(bool script_removed){mScriptRemoved = script_removed;};
private:
- void onBtnHelp();
void onBtnDynamicHelp();
void onBtnUndoChanges();
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 9d8be4b2fe..1e91da529c 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -401,7 +401,7 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
{
const U32 ext_length = 3;
std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length);
-
+ LLStringUtil::toLower(extension);
// We only support saving in PNG or TGA format
LLPointer<LLImageFormatted> image;
if(extension == "png")
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 083a913ef8..416848f9af 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -229,6 +229,33 @@ void LLProgressView::drawStartTexture(F32 alpha)
gGL.popMatrix();
}
+void LLProgressView::drawLogos(F32 alpha)
+{
+ if (mLogosList.empty())
+ {
+ return;
+ }
+
+ // logos are tied to label,
+ // due to potential resizes we have to figure offsets out on draw or resize
+ LLTextBox *logos_label = getChild<LLTextBox>("logos_lbl");
+ S32 offset_x, offset_y;
+ logos_label->localPointToScreen(0, 0, &offset_x, &offset_y);
+ std::vector<TextureData>::const_iterator iter = mLogosList.begin();
+ std::vector<TextureData>::const_iterator end = mLogosList.end();
+ for (; iter != end; iter++)
+ {
+ gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x,
+ iter->mDrawRect.mBottom + offset_y,
+ iter->mDrawRect.getWidth(),
+ iter->mDrawRect.getHeight(),
+ iter->mTexturep.get(),
+ UI_VERTEX_COLOR % alpha,
+ FALSE,
+ iter->mClipRect,
+ iter->mOffsetRect);
+ }
+}
void LLProgressView::draw()
{
@@ -245,6 +272,7 @@ void LLProgressView::draw()
}
LLPanel::draw();
+ drawLogos(alpha);
return;
}
@@ -257,6 +285,7 @@ void LLProgressView::draw()
drawStartTexture(alpha);
LLPanel::draw();
+ drawLogos(alpha);
// faded out completely - remove panel and reveal world
if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
@@ -283,7 +312,7 @@ void LLProgressView::draw()
// FIXME: this causes a crash that i haven't been able to fix
mMediaCtrl->unloadMediaSource();
- gStartTexture = NULL;
+ releaseTextures();
}
return;
}
@@ -291,6 +320,7 @@ void LLProgressView::draw()
drawStartTexture(1.0f);
// draw children
LLPanel::draw();
+ drawLogos(1.0f);
}
void LLProgressView::setText(const std::string& text)
@@ -309,6 +339,199 @@ void LLProgressView::setMessage(const std::string& msg)
getChild<LLUICtrl>("message_text")->setValue(mMessage);
}
+void LLProgressView::loadLogo(const std::string &path,
+ const U8 image_codec,
+ const LLRect &pos_rect,
+ const LLRectf &clip_rect,
+ const LLRectf &offset_rect)
+{
+ // We need these images very early, so we have to force-load them, otherwise they might not load in time.
+ if (!gDirUtilp->fileExists(path))
+ {
+ return;
+ }
+
+ LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
+ if (!start_image_frmted->load(path))
+ {
+ LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+ if (!start_image_frmted->decode(raw, 0.0f))
+ {
+ LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL;
+ return;
+ }
+ // HACK: getLocalTexture allows only power of two dimentions
+ raw->expandToPowerOfTwo();
+
+ TextureData data;
+ data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ data.mDrawRect = pos_rect;
+ data.mClipRect = clip_rect;
+ data.mOffsetRect = offset_rect;
+ mLogosList.push_back(data);
+}
+
+void LLProgressView::initLogos()
+{
+ mLogosList.clear();
+
+ const U8 image_codec = IMG_CODEC_PNG;
+ const LLRectf default_clip(0.f, 1.f, 1.f, 0.f);
+ const S32 default_height = 28;
+ const S32 default_pad = 15;
+
+ S32 icon_width, icon_height;
+
+ // We don't know final screen rect yet, so we can't precalculate position fully
+ LLTextBox *logos_label = getChild<LLTextBox>("logos_lbl");
+ S32 texture_start_x = logos_label->getFont()->getWidthF32(logos_label->getText()) + default_pad;
+ S32 texture_start_y = -7;
+
+ // Normally we would just preload these textures from textures.xml,
+ // and display them via icon control, but they are only needed on
+ // startup and preloaded/UI ones stay forever
+ // (and this code was done already so simply reused it)
+ std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons");
+
+ temp_str += gDirUtilp->getDirDelimiter();
+
+#ifdef LL_FMODSTUDIO
+ // original image size is 264x96, it is on longer side but
+ // with no internal paddings so it gets additional padding
+ icon_width = 77;
+ icon_height = 21;
+ S32 pad_fmod_y = 4;
+ texture_start_x++;
+ loadLogo(temp_str + "fmod_logo.png",
+ image_codec,
+ LLRect(texture_start_x, texture_start_y + pad_fmod_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_fmod_y),
+ default_clip,
+ default_clip);
+
+ texture_start_x += icon_width + default_pad + 1;
+#endif //LL_FMODSTUDIO
+#ifdef LL_HAVOK
+ // original image size is 342x113, central element is on a larger side
+ // plus internal padding, so it gets slightly more height than desired 32
+ icon_width = 88;
+ icon_height = 29;
+ S32 pad_havok_y = -1;
+ loadLogo(temp_str + "havok_logo.png",
+ image_codec,
+ LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y),
+ default_clip,
+ default_clip);
+
+ texture_start_x += icon_width + default_pad;
+#endif //LL_HAVOK
+
+ // 108x41
+ icon_width = 74;
+ icon_height = default_height;
+ loadLogo(temp_str + "vivox_logo.png",
+ image_codec,
+ LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y),
+ default_clip,
+ default_clip);
+}
+
+void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
+{
+ if (gStartTexture.notNull())
+ {
+ gStartTexture = NULL;
+ LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
+ }
+
+ LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL;
+
+ U8 image_codec = IMG_CODEC_PNG;
+ std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
+
+ if ((S32)START_LOCATION_ID_LAST == location_id)
+ {
+ temp_str += LLStartUp::getScreenLastFilename();
+ }
+ else
+ {
+ std::string path = temp_str + LLStartUp::getScreenHomeFilename();
+
+ if (!gDirUtilp->fileExists(path) && is_in_production)
+ {
+ // Fallback to old file, can be removed later
+ // Home image only sets when user changes home, so it will take time for users to switch to pngs
+ temp_str += "screen_home.bmp";
+ image_codec = IMG_CODEC_BMP;
+ }
+ else
+ {
+ temp_str = path;
+ }
+ }
+
+ LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
+
+ // Turn off start screen to get around the occasional readback
+ // driver bug
+ if (!gSavedSettings.getBOOL("UseStartScreen"))
+ {
+ LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL;
+ return;
+ }
+ else if (!start_image_frmted->load(temp_str))
+ {
+ LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL;
+ gStartTexture = NULL;
+ }
+ else
+ {
+ gStartImageWidth = start_image_frmted->getWidth();
+ gStartImageHeight = start_image_frmted->getHeight();
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+ if (!start_image_frmted->decode(raw, 0.0f))
+ {
+ LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
+ gStartTexture = NULL;
+ }
+ else
+ {
+ // HACK: getLocalTexture allows only power of two dimentions
+ raw->expandToPowerOfTwo();
+ gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ }
+ }
+
+ if (gStartTexture.isNull())
+ {
+ gStartTexture = LLViewerTexture::sBlackImagep;
+ gStartImageWidth = gStartTexture->getWidth();
+ gStartImageHeight = gStartTexture->getHeight();
+ }
+}
+
+void LLProgressView::initTextures(S32 location_id, bool is_in_production)
+{
+ initStartTexture(location_id, is_in_production);
+ initLogos();
+
+ childSetVisible("panel_icons", mLogosList.empty() ? FALSE : TRUE);
+ childSetVisible("panel_top_spacer", mLogosList.empty() ? TRUE : FALSE);
+}
+
+void LLProgressView::releaseTextures()
+{
+ gStartTexture = NULL;
+ mLogosList.clear();
+
+ childSetVisible("panel_top_spacer", TRUE);
+ childSetVisible("panel_icons", FALSE);
+}
+
void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label)
{
mCancelBtn->setVisible( b );
@@ -325,6 +548,7 @@ void LLProgressView::onCancelButtonClicked(void*)
// cancel is pressed while teleporting inside region (EXT-4911)
if (LLStartUp::getStartupState() < STATE_STARTED)
{
+ LL_INFOS() << "User requesting quit during login" << LL_ENDL;
LLAppViewer::instance()->requestQuit();
}
else
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 813576b21d..56377a5889 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -35,6 +35,7 @@
class LLImageRaw;
class LLButton;
class LLProgressBar;
+class LLViewerTexture;
class LLProgressView :
public LLPanel,
@@ -51,6 +52,7 @@ public:
/*virtual*/ void draw();
void drawStartTexture(F32 alpha);
+ void drawLogos(F32 alpha);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
@@ -70,6 +72,10 @@ public:
void setStartupComplete();
+ // we have to preload local textures to make sure they won't be grey
+ void initTextures(S32 location_id, bool is_in_production);
+ void releaseTextures();
+
void setCancelButtonVisible(BOOL b, const std::string& label);
static void onCancelButtonClicked( void* );
@@ -95,6 +101,25 @@ protected:
bool handleUpdate(const LLSD& event_data);
static void onIdle(void* user_data);
+ void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect);
+ // logos have unusual location and need to be preloaded to not appear grey, then deleted
+ void initLogos();
+ // Loads a bitmap to display during load
+ void initStartTexture(S32 location_id, bool is_in_production);
+
+private:
+ // We need to draw textures on login, but only once.
+ // So this vector gets filled up for textures to render and gets cleaned later
+ // Some textures have unusual requirements, so we are rendering directly
+ class TextureData
+ {
+ public:
+ LLPointer<LLViewerTexture> mTexturep;
+ LLRect mDrawRect;
+ LLRectf mClipRect;
+ LLRectf mOffsetRect;
+ };
+ std::vector<TextureData> mLogosList;
};
#endif // LL_LLPROGRESSVIEW_H
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 1b4295ddad..18b669ff4f 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -53,7 +53,7 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL
LLSINGLETON_EMPTY_CTOR(LLRecentPeople);
LOG_CLASS(LLRecentPeople);
public:
- typedef std::map <LLUUID, F32> id_to_time_map_t;
+ typedef std::map <LLUUID, F64> id_to_time_map_t;
typedef boost::signals2::signal<void ()> signal_t;
/**
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 5b0d189137..70c117be44 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -45,7 +45,7 @@ struct LLParcelData
std::string desc;
S32 actual_area;
S32 billable_area;
- U8 flags;
+ U8 flags; // group owned, maturity
F32 global_x;
F32 global_y;
F32 global_z;
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 5ab0013055..f9baf5fbd3 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -526,170 +526,167 @@ void LLSceneMonitor::fetchQueryResult()
//dump results to a file _scene_xmonitor_results.csv
void LLSceneMonitor::dumpToFile(std::string file_name)
-{ using namespace LLTrace;
-
+{
if (!hasResults()) return;
LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;
-
- llofstream os(file_name.c_str());
-
- os << std::setprecision(10);
-
- PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
- const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
-
- F64Seconds frame_time;
-
- os << "Stat";
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
- os << ", " << frame_time.value();
- }
- os << '\n';
-
- os << "Sample period(s)";
- for (S32 frame = 1; frame <= frame_count; frame++)
+ try
{
- frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
- os << ", " << frame_time.value();
- }
- os << '\n';
+ llofstream os(file_name.c_str());
+ os << std::setprecision(10);
- typedef StatType<CountAccumulator> trace_count;
- for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances();
- it != end_it;
- ++it)
- {
- std::ostringstream row;
- row << std::setprecision(10);
+ LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
+ const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
- row << it->getName();
+ F64Seconds frame_time;
- const char* unit_label = it->getUnitLabel();
- if(unit_label[0])
+ os << "Stat";
+ for (S32 frame = 1; frame <= frame_count; frame++)
{
- row << "(" << unit_label << ")";
+ frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+ os << ", " << frame_time.value();
}
+ os << '\n';
- S32 samples = 0;
-
+ os << "Sample period(s)";
for (S32 frame = 1; frame <= frame_count; frame++)
{
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- row << ", " << recording.getSum(*it);
+ frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+ os << ", " << frame_time.value();
}
+ os << '\n';
- row << '\n';
- if (samples > 0)
+ typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
+ for (auto& it : trace_count::instance_snapshot())
{
- os << row.str();
- }
- }
+ std::ostringstream row;
+ row << std::setprecision(10);
- typedef StatType<EventAccumulator> trace_event;
+ row << it.getName();
- for (trace_event::instance_iter it = trace_event::beginInstances(), end_it = trace_event::endInstances();
- it != end_it;
- ++it)
- {
- std::ostringstream row;
- row << std::setprecision(10);
- row << it->getName();
-
- const char* unit_label = it->getUnitLabel();
- if(unit_label[0])
- {
- row << "(" << unit_label << ")";
- }
+ const char* unit_label = it.getUnitLabel();
+ if (unit_label[0])
+ {
+ row << "(" << unit_label << ")";
+ }
- S32 samples = 0;
+ S32 samples = 0;
- for (S32 frame = 1; frame <= frame_count; frame++)
- {
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- F64 mean = recording.getMean(*it);
- if (llisnan(mean))
+ for (S32 frame = 1; frame <= frame_count; frame++)
{
- row << ", n/a";
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ samples += recording.getSampleCount(it);
+ row << ", " << recording.getSum(it);
}
- else
+
+ row << '\n';
+
+ if (samples > 0)
{
- row << ", " << mean;
+ os << row.str();
}
}
- row << '\n';
+ typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
- if (samples > 0)
+ for (auto& it : trace_event::instance_snapshot())
{
- os << row.str();
- }
- }
+ std::ostringstream row;
+ row << std::setprecision(10);
+ row << it.getName();
- typedef StatType<SampleAccumulator> trace_sample;
+ const char* unit_label = it.getUnitLabel();
+ if (unit_label[0])
+ {
+ row << "(" << unit_label << ")";
+ }
- for (trace_sample::instance_iter it = trace_sample::beginInstances(), end_it = trace_sample::endInstances();
- it != end_it;
- ++it)
- {
- std::ostringstream row;
- row << std::setprecision(10);
- row << it->getName();
+ S32 samples = 0;
- const char* unit_label = it->getUnitLabel();
- if(unit_label[0])
- {
- row << "(" << unit_label << ")";
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ samples += recording.getSampleCount(it);
+ F64 mean = recording.getMean(it);
+ if (llisnan(mean))
+ {
+ row << ", n/a";
+ }
+ else
+ {
+ row << ", " << mean;
+ }
+ }
+
+ row << '\n';
+
+ if (samples > 0)
+ {
+ os << row.str();
+ }
}
- S32 samples = 0;
+ typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
- for (S32 frame = 1; frame <= frame_count; frame++)
+ for (auto& it : trace_sample::instance_snapshot())
{
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- F64 mean = recording.getMean(*it);
- if (llisnan(mean))
+ std::ostringstream row;
+ row << std::setprecision(10);
+ row << it.getName();
+
+ const char* unit_label = it.getUnitLabel();
+ if (unit_label[0])
{
- row << ", n/a";
+ row << "(" << unit_label << ")";
}
- else
+
+ S32 samples = 0;
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
{
- row << ", " << mean;
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ samples += recording.getSampleCount(it);
+ F64 mean = recording.getMean(it);
+ if (llisnan(mean))
+ {
+ row << ", n/a";
+ }
+ else
+ {
+ row << ", " << mean;
+ }
}
- }
- row << '\n';
+ row << '\n';
- if (samples > 0)
- {
- os << row.str();
+ if (samples > 0)
+ {
+ os << row.str();
+ }
}
- }
-
- typedef StatType<MemAccumulator> trace_mem;
- for (trace_mem::instance_iter it = trace_mem::beginInstances(), end_it = trace_mem::endInstances();
- it != end_it;
- ++it)
- {
- os << it->getName() << "(KiB)";
- for (S32 frame = 1; frame <= frame_count; frame++)
+ typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
+ for (auto& it : trace_mem::instance_snapshot())
{
- os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).valueInUnits<LLUnits::Kilobytes>();
+ os << it.getName() << "(KiB)";
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
+ }
+
+ os << '\n';
}
- os << '\n';
+ os.flush();
+ os.close();
+ }
+ catch (const std::ios_base::failure &e)
+ {
+ LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL;
}
-
- os.flush();
- os.close();
}
//-------------------------------------------------------------------------------------------------------------
diff --git a/indra/newview/llscriptruntimeperms.h b/indra/newview/llscriptruntimeperms.h
index 51f57afdc9..f692c0ad01 100644
--- a/indra/newview/llscriptruntimeperms.h
+++ b/indra/newview/llscriptruntimeperms.h
@@ -37,7 +37,7 @@ typedef struct _script_perm {
question(q), permbit(b), caution(c) {}
} script_perm_t;
-const U32 NUM_SCRIPT_PERMISSIONS = 16;
+const U32 NUM_SCRIPT_PERMISSIONS = 18;
const S32 SCRIPT_PERMISSION_DEBIT = 0;
const S32 SCRIPT_PERMISSION_TRIGGER_ANIMATION = 3;
const S32 SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS = 14;
@@ -58,7 +58,9 @@ static const boost::array<script_perm_t, NUM_SCRIPT_PERMISSIONS> SCRIPT_PERMISSI
_script_perm("JoinAnExperience", (0x1 << 13), false),
_script_perm("SilentlyManageEstateAccess", (0x1 << 14), false),
_script_perm("OverrideYourAnimations", (0x1 << 15), false),
- _script_perm("ScriptReturnObjects", (0x1 << 16), false)
-}};
+ _script_perm("ScriptReturnObjects", (0x1 << 16), false),
+ _script_perm("ForceSitAvatar", (0x1 << 17), false),
+ _script_perm("ChangeEnvSettings", (0x1 << 18), false)
+ } };
#endif // LL_LLSCRIPTRUNTIME_PERMS_H
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index 93143eb33f..1119e80005 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -68,7 +68,10 @@ ll::prefs::PanelData::~PanelData()
bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
{
for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
- (*itr)->setNotHighlighted( );
+ (*itr)->setNotHighlighted();
+
+ for (tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr)
+ (*itr)->setNotHighlighted();
if (aFilter.empty())
{
@@ -85,6 +88,15 @@ bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
return bVisible;
}
+void ll::prefs::PanelData::setNotHighlighted()
+{
+ for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
+ (*itr)->setNotHighlighted();
+
+ for (tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr)
+ (*itr)->setNotHighlighted();
+}
+
bool ll::prefs::TabContainerData::hightlightAndHide( LLWString const &aFilter )
{
for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr )
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 9741557e49..e033cae3ab 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -73,6 +73,7 @@ namespace ll
virtual ~PanelData();
+ void setNotHighlighted();
virtual bool hightlightAndHide( LLWString const &aFilter );
};
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 72d7cf1e45..b9259cb18d 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -64,7 +64,7 @@ void initializeSecHandler()
{
handler->init();
}
- catch (LLProtectedDataException e)
+ catch (LLProtectedDataException& e)
{
exception_msg = e.what();
}
@@ -117,7 +117,7 @@ LLSD LLCredential::getLoginParams()
else if (mIdentifier["type"].asString() == "account")
{
result["username"] = mIdentifier["account_name"];
- result["passwd"] = mAuthenticator["secret"];
+ result["passwd"] = mAuthenticator["secret"].asString();
username = result["username"].asString();
}
}
@@ -154,3 +154,10 @@ void LLCredential::authenticatorType(std::string &idType)
}
}
+
+LLCertException::LLCertException(const LLSD& cert_data, const std::string& msg)
+ : LLException(msg),
+ mCertData(cert_data)
+{
+ LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
+}
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index d207f3b5b7..14059f828a 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -75,6 +75,7 @@
#define CERT_EXTENDED_KEY_USAGE "extendedKeyUsage"
#define CERT_EKU_SERVER_AUTH SN_server_auth
+#define CERT_EKU_TLS_SERVER_AUTH LN_server_auth
#define CERT_SUBJECT_KEY_IDENTFIER "subjectKeyIdentifier"
#define CERT_AUTHORITY_KEY_IDENTIFIER "authorityKeyIdentifier"
@@ -334,17 +335,23 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred);
class LLCertException: public LLException
{
public:
- LLCertException(const LLSD& cert_data, const std::string& msg): LLException(msg),
- mCertData(cert_data)
- {
- LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
- }
+ LLCertException(const LLSD& cert_data, const std::string& msg);
virtual ~LLCertException() throw() {}
LLSD getCertData() const { return mCertData; }
protected:
LLSD mCertData;
};
+class LLAllocationCertException : public LLCertException
+{
+public:
+ LLAllocationCertException(const LLSD& cert_data) : LLCertException(cert_data, "CertAllocationFailure")
+ {
+ }
+ virtual ~LLAllocationCertException() throw() {}
+protected:
+};
+
class LLInvalidCertificate : public LLCertException
{
public:
@@ -464,7 +471,19 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id)=0;
-
+
+ // persist data in a protected store's map
+ virtual void addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data)=0;
+
+ // remove data from protected store's map
+ virtual void removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem)=0;
+
+public:
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator)=0;
@@ -474,6 +493,42 @@ public:
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
+
+ // has map of credentials declared as specific storage
+ virtual bool hasCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
+
+ // returns true if map is empty or does not exist
+ virtual bool emptyCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
+
+ // load map of credentials from specific storage
+ typedef std::map<std::string, LLPointer<LLCredential> > credential_map_t;
+ virtual void loadCredentialMap(const std::string& storage,
+ const std::string& grid,
+ credential_map_t& credential_map)=0;
+
+ // load single username from map of credentials from specific storage
+ virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid)=0;
+
+ // add item to map of credentials from specific storage
+ virtual void addToCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred,
+ bool save_authenticator)=0;
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred)=0;
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid)=0;
+
+ virtual void removeCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
};
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 9ab9e4a1a2..737ef30ada 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -52,6 +52,7 @@
#include "llmachineid.h"
+static const std::string DEFAULT_CREDENTIAL_STORAGE = "credential";
// 128 bits of salt data...
#define STORE_SALT_SIZE 16
@@ -77,16 +78,16 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert,
BIO * pem_bio = BIO_new_mem_buf((void*)pem_cert.c_str(), pem_cert.length());
if(pem_bio == NULL)
{
- LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
- LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
+ LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
+ LLTHROW(LLAllocationCertException(LLSD::emptyMap()));
}
mCert = NULL;
PEM_read_bio_X509(pem_bio, &mCert, 0, NULL);
BIO_free(pem_bio);
if (!mCert)
{
- LL_WARNS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL;
- LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
+ LL_WARNS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL;
+ LLTHROW(LLInvalidCertificate(LLSD::emptyMap()));
}
}
@@ -923,9 +924,13 @@ void _validateCert(int validation_policy,
LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
}
// only validate EKU if the cert has it
- if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE) && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray() &&
- (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],
- LLSD((std::string)CERT_EKU_SERVER_AUTH))))
+ if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE)
+ && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray()
+ && (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],
+ LLSD((std::string)CERT_EKU_TLS_SERVER_AUTH)))
+ && (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],
+ LLSD((std::string)CERT_EKU_SERVER_AUTH)))
+ )
{
LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
}
@@ -1533,6 +1538,38 @@ void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type,
mProtectedDataMap[data_type][data_id] = data;
}
+// persist data in a protected store's map
+void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data)
+{
+ if (!mProtectedDataMap.has(data_type) || !mProtectedDataMap[data_type].isMap()) {
+ mProtectedDataMap[data_type] = LLSD::emptyMap();
+ }
+
+ if (!mProtectedDataMap[data_type].has(data_id) || !mProtectedDataMap[data_type][data_id].isMap()) {
+ mProtectedDataMap[data_type][data_id] = LLSD::emptyMap();
+ }
+
+ mProtectedDataMap[data_type][data_id][map_elem] = data;
+}
+
+// remove data from protected store's map
+void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem)
+{
+ if (mProtectedDataMap.has(data_type) &&
+ mProtectedDataMap[data_type].isMap() &&
+ mProtectedDataMap[data_type].has(data_id) &&
+ mProtectedDataMap[data_type][data_id].isMap() &&
+ mProtectedDataMap[data_type][data_id].has(map_elem))
+ {
+ mProtectedDataMap[data_type][data_id].erase(map_elem);
+ }
+}
+
//
// Create a credential object from an identifier and authenticator. credentials are
// per grid.
@@ -1545,10 +1582,10 @@ LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string
return result;
}
-// Load a credential from the credential store, given the grid
+// Load a credential from default credential store, given the grid
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid)
{
- LLSD credential = getProtectedData("credential", grid);
+ LLSD credential = getProtectedData(DEFAULT_CREDENTIAL_STORAGE, grid);
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if(credential.isMap() &&
credential.has("identifier"))
@@ -1603,7 +1640,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
- setProtectedData("credential", cred->getGrid(), credential);
+ setProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid(), credential);
//*TODO: If we're saving Agni credentials, should we write the
// credentials to the legacy password.dat/etc?
_writeProtectedData();
@@ -1613,11 +1650,150 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred)
{
LLSD undefVal;
- deleteProtectedData("credential", cred->getGrid());
+ deleteProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
+// has map of credentials declared as specific storage
+bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+
+ return credential.isMap();
+}
+
+// returns true if map is empty or does not exist
+bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+
+ return !credential.isMap() || credential.size() == 0;
+}
+
+// Load map of credentials from specified credential store, given the grid
+void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+ if (credential.isMap())
+ {
+ LLSD::map_const_iterator crd_it = credential.beginMap();
+ for (; crd_it != credential.endMap(); crd_it++)
+ {
+ LLSD::String name = crd_it->first;
+ const LLSD &link_map = crd_it->second;
+ LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
+ if (link_map.has("identifier"))
+ {
+ LLSD identifier = link_map["identifier"];
+ LLSD authenticator;
+ if (link_map.has("authenticator"))
+ {
+ authenticator = link_map["authenticator"];
+ }
+ result->setCredentialData(identifier, authenticator);
+ }
+ credential_map[name] = result;
+ }
+ }
+}
+
+LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
+
+ LLSD credential = getProtectedData(storage, grid);
+ if (credential.isMap() && credential.has(userkey) && credential[userkey].has("identifier"))
+ {
+ LLSD identifier = credential[userkey]["identifier"];
+ LLSD authenticator;
+ if (credential[userkey].has("authenticator"))
+ {
+ authenticator = credential[userkey]["authenticator"];
+ }
+ result->setCredentialData(identifier, authenticator);
+ }
+
+ return result;
+}
+
+// add item to map of credentials from specific storage
+void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ std::string user_id = cred->userID();
+ LLSD credential = LLSD::emptyMap();
+ credential["identifier"] = cred->getIdentifier();
+ if (save_authenticator)
+ {
+ credential["authenticator"] = cred->getAuthenticator();
+ }
+ LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
+ addToProtectedMap(storage, cred->getGrid(), user_id, credential);
+
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD undefVal;
+ removeFromProtectedMap(storage, cred->getGrid(), cred->userID());
+ cred->setCredentialData(undefVal, undefVal);
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD undefVal;
+ LLPointer<LLCredential> cred = loadFromCredentialMap(storage, grid, userkey);
+ removeFromProtectedMap(storage, grid, userkey);
+ cred->setCredentialData(undefVal, undefVal);
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid)
+{
+ deleteProtectedData(storage, grid);
+ _writeProtectedData();
+}
+
// load the legacy hash for agni, and decrypt it given the
// mac address
std::string LLSecAPIBasicHandler::_legacyLoadPassword()
@@ -1656,15 +1832,18 @@ std::string LLSecAPIBasicCredential::userID() const
}
else if ((std::string)mIdentifier["type"] == "agent")
{
- return (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
+ std::string id = (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
+ LLStringUtil::toLower(id);
+ return id;
}
else if ((std::string)mIdentifier["type"] == "account")
{
- return (std::string)mIdentifier["account_name"];
+ std::string id = (std::string)mIdentifier["account_name"];
+ LLStringUtil::toLower(id);
+ return id;
}
return "unknown";
-
}
// return a printable user identifier
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index c35617f564..0bc7f5230f 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -211,8 +211,9 @@ class LLSecAPIBasicCredential : public LLCredential
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
- // return a value representing the user id, (could be guid, name, whatever)
- virtual std::string userID() const;
+ // return a value representing the user id, used for server and voice
+ // (could be guid, name in format "name_resident", whatever)
+ virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
@@ -246,7 +247,10 @@ public:
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
-
+
+ // protectedData functions technically should be pretected or private,
+ // they are not because of llsechandler_basic_test imlementation
+
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
@@ -259,19 +263,68 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
-
+
+ // persist data in a protected store's map
+ virtual void addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data);
+
+ // remove data from protected store's map
+ virtual void removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem);
+
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
-
+
+ // load single credencial from default storage
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
+ // save credencial to default storage
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
-
+
+ // has map of credentials declared as specific storage
+ virtual bool hasCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+ // returns true if map is empty or does not exist
+ virtual bool emptyCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+ // load map of credentials from specific storage
+ virtual void loadCredentialMap(const std::string& storage,
+ const std::string& grid,
+ credential_map_t& credential_map);
+
+ // load single username from map of credentials from specific storage
+ virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid);
+
+ // add item to map of credentials from specific storage
+ virtual void addToCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred,
+ bool save_authenticator);
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred);
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid);
+
+ virtual void removeCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+
protected:
void _readProtectedData();
void _writeProtectedData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index f849fecaf6..50884762a8 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -35,7 +35,6 @@
#include "llcachename.h"
#include "llavatarnamecache.h"
#include "lldbstrings.h"
-#include "lleconomy.h"
#include "llgl.h"
#include "llmediaentry.h"
#include "llrender.h"
@@ -304,6 +303,27 @@ void LLSelectMgr::updateEffects()
}
}
+void LLSelectMgr::resetObjectOverrides()
+{
+ resetObjectOverrides(getSelection());
+}
+
+void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
+{
+ struct f : public LLSelectedNodeFunctor
+ {
+ virtual bool apply(LLSelectNode* node)
+ {
+ node->mLastPositionLocal.setVec(0, 0, 0);
+ node->mLastRotation = LLQuaternion();
+ node->mLastScale.setVec(0, 0, 0);
+ return true;
+ }
+ } func;
+
+ selected_handle->applyToNodes(&func);
+}
+
void LLSelectMgr::overrideObjectUpdates()
{
//override any position updates from simulator on objects being edited
@@ -3911,11 +3931,11 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r
return TRUE;
}
-BOOL LLSelectMgr::isSelfAvatarSelected()
+BOOL LLSelectMgr::isMovableAvatarSelected()
{
if (mAllowSelectAvatar)
{
- return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp);
+ return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject()->isAvatar()) && getSelection()->getFirstMoveableNode(TRUE);
}
return FALSE;
}
@@ -5131,18 +5151,27 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
bool link_operation = message_name == "ObjectLink";
- //clear update override data (allow next update through)
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->mLastPositionLocal.setVec(0,0,0);
- node->mLastRotation = LLQuaternion();
- node->mLastScale.setVec(0,0,0);
- return true;
- }
- } func;
- selected_handle->applyToNodes(&func);
+ if (mAllowSelectAvatar)
+ {
+ if (selected_handle->getObjectCount() == 1
+ && selected_handle->getFirstObject() != NULL
+ && selected_handle->getFirstObject()->isAvatar())
+ {
+ // Server doesn't move avatars at the moment, it is a local debug feature,
+ // but server does update position regularly, so do not drop mLastPositionLocal
+ // Position override for avatar gets reset in LLAgentCamera::resetView().
+ }
+ else
+ {
+ // drop mLastPositionLocal (allow next update through)
+ resetObjectOverrides(selected_handle);
+ }
+ }
+ else
+ {
+ //clear update override data (allow next update through)
+ resetObjectOverrides(selected_handle);
+ }
std::queue<LLSelectNode*> nodes_to_send;
@@ -5426,7 +5455,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
}
else
{
- if (node->mInventorySerial != inv_serial)
+ if (node->mInventorySerial != inv_serial && node->getObject())
{
node->getObject()->dirtyInventory();
}
@@ -6852,51 +6881,26 @@ void LLSelectMgr::pauseAssociatedAvatars()
mSelectedObjects->mSelectType = getSelectTypeForObject(object);
- bool is_attached = false;
- if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT &&
- isAgentAvatarValid())
+ LLVOAvatar* parent_av = NULL;
+ if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT)
{
// Selection can be obsolete, confirm that this is an attachment
- LLViewerObject* parent = (LLViewerObject*)object->getParent();
- while (parent != NULL)
- {
- if (parent->isAvatar())
- {
- is_attached = true;
- break;
- }
- else
- {
- parent = (LLViewerObject*)parent->getParent();
- }
- }
+ // and find parent avatar
+ parent_av = object->getAvatarAncestor();
}
-
- if (is_attached)
+ // Can be both an attachment and animated object
+ if (parent_av)
{
- if (object->isAnimatedObject())
- {
- // Is an animated object attachment.
- // Pause both the control avatar and the avatar it's attached to.
- if (object->getControlAvatar())
- {
- mPauseRequests.push_back(object->getControlAvatar()->requestPause());
- }
- mPauseRequests.push_back(gAgentAvatarp->requestPause());
- }
- else
- {
- // Is a regular attachment. Pause the avatar it's attached to.
- mPauseRequests.push_back(gAgentAvatarp->requestPause());
- }
+ // It's an attachment. Pause the avatar it's attached to.
+ mPauseRequests.push_back(parent_av->requestPause());
}
- else if (object && object->isAnimatedObject() && object->getControlAvatar())
+
+ if (object->isAnimatedObject() && object->getControlAvatar())
{
- // Is a non-attached animated object. Pause the control avatar.
+ // It's an animated object. Pause the control avatar.
mPauseRequests.push_back(object->getControlAvatar()->requestPause());
}
-
}
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 3bed484b58..57fdfce152 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -458,6 +458,13 @@ public:
void clearSelections();
void update();
void updateEffects(); // Update HUD effects
+
+ // When we edit object's position/rotation/scale we set local
+ // overrides and ignore any updates (override received valeus).
+ // When we send data to server, we send local values and reset
+ // overrides
+ void resetObjectOverrides();
+ void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
void overrideObjectUpdates();
// Returns the previous value of mForceSelection
@@ -725,7 +732,7 @@ public:
LLPermissions* findObjectPermissions(const LLViewerObject* object);
- BOOL isSelfAvatarSelected();
+ BOOL isMovableAvatarSelected();
void selectDelete(); // Delete on simulator
void selectForceDelete(); // just delete, no into trash
diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp
new file mode 100644
index 0000000000..4b36822e9a
--- /dev/null
+++ b/indra/newview/llsetkeybinddialog.cpp
@@ -0,0 +1,380 @@
+/**
+ * @file llsetkeybinddialog.cpp
+ * @brief LLSetKeyBindDialog class implementation.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llsetkeybinddialog.h"
+
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "lleventtimer.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llkeyconflict.h"
+#include "llviewercontrol.h"
+
+class LLSetKeyBindDialog::Updater : public LLEventTimer
+{
+public:
+
+ typedef boost::function<void(MASK)> callback_t;
+
+ Updater(callback_t cb, F32 period, MASK mask)
+ :LLEventTimer(period),
+ mMask(mask),
+ mCallback(cb)
+ {
+ mEventTimer.start();
+ }
+
+ virtual ~Updater(){}
+
+protected:
+ BOOL tick()
+ {
+ mCallback(mMask);
+ // Deletes itseft after execution
+ return TRUE;
+ }
+
+private:
+ MASK mMask;
+ callback_t mCallback;
+};
+
+bool LLSetKeyBindDialog::sRecordKeys = false;
+
+LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)
+ : LLModalDialog(key),
+ pParent(NULL),
+ mKeyFilterMask(DEFAULT_KEY_FILTER),
+ pUpdater(NULL),
+ mLastMaskKey(0),
+ mContextConeOpacity(0.f),
+ mContextConeInAlpha(0.f),
+ mContextConeOutAlpha(0.f),
+ mContextConeFadeTime(0.f)
+{
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
+}
+
+LLSetKeyBindDialog::~LLSetKeyBindDialog()
+{
+}
+
+//virtual
+BOOL LLSetKeyBindDialog::postBuild()
+{
+ childSetAction("SetEmpty", onBlank, this);
+ childSetAction("Default", onDefault, this);
+ childSetAction("Cancel", onCancel, this);
+ getChild<LLUICtrl>("Cancel")->setFocus(TRUE);
+
+ pCheckBox = getChild<LLCheckBoxCtrl>("apply_all");
+ pDesription = getChild<LLTextBase>("descritption");
+
+ gFocusMgr.setKeystrokesOnly(TRUE);
+
+ return TRUE;
+}
+
+//virtual
+void LLSetKeyBindDialog::onOpen(const LLSD& data)
+{
+ sRecordKeys = true;
+ LLModalDialog::onOpen(data);
+}
+
+//virtual
+void LLSetKeyBindDialog::onClose(bool app_quiting)
+{
+ sRecordKeys = false;
+ if (pParent)
+ {
+ pParent->onCancelKeyBind();
+ pParent = NULL;
+ }
+ if (pUpdater)
+ {
+ // Doubleclick timer has't fired, delete it
+ delete pUpdater;
+ pUpdater = NULL;
+ }
+ LLModalDialog::onClose(app_quiting);
+}
+
+void LLSetKeyBindDialog::drawFrustum()
+{
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
+}
+
+//virtual
+void LLSetKeyBindDialog::draw()
+{
+ drawFrustum();
+ LLModalDialog::draw();
+}
+
+void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask)
+{
+ pParent = parent;
+ mFrustumOrigin = frustum_origin->getHandle();
+ mKeyFilterMask = key_mask;
+
+ std::string input;
+ if ((key_mask & ALLOW_MOUSE) != 0)
+ {
+ input = getString("mouse");
+ }
+ if ((key_mask & ALLOW_KEYS) != 0)
+ {
+ if (!input.empty())
+ {
+ input += ", ";
+ }
+ input += getString("keyboard");
+ }
+ pDesription->setText(getString("basic_description"));
+ pDesription->setTextArg("[INPUT]", input);
+}
+
+// static
+bool LLSetKeyBindDialog::recordKey(KEY key, MASK mask, BOOL down)
+{
+ if (sRecordKeys)
+ {
+ LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+ if (dialog && dialog->getVisible())
+ {
+ return dialog->recordAndHandleKey(key, mask, down);
+ }
+ else
+ {
+ LL_WARNS() << "Key recording was set despite no open dialog" << LL_ENDL;
+ sRecordKeys = false;
+ }
+ }
+ return false;
+}
+
+bool LLSetKeyBindDialog::recordAndHandleKey(KEY key, MASK mask, BOOL down)
+{
+ if ((key == 'Q' && mask == MASK_CONTROL)
+ || key == KEY_ESCAPE)
+ {
+ sRecordKeys = false;
+ closeFloater();
+ return true;
+ }
+
+ if (key == KEY_DELETE)
+ {
+ setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);
+ sRecordKeys = false;
+ closeFloater();
+ return false;
+ }
+
+ // forbidden keys
+ if (key == KEY_NONE
+ || key == KEY_RETURN
+ || key == KEY_BACKSPACE)
+ {
+ return false;
+ }
+
+ if (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT)
+ {
+ // Mask keys get special treatment
+ if ((mKeyFilterMask & ALLOW_MASKS) == 0)
+ {
+ // Masks by themself are not allowed
+ return false;
+ }
+ if (down == TRUE)
+ {
+ // Most keys are handled on 'down' event because menu is handled on 'down'
+ // masks are exceptions to let other keys be handled
+ mLastMaskKey = key;
+ return false;
+ }
+ if (mLastMaskKey != key)
+ {
+ // This was mask+key combination that got rejected, don't handle mask's key
+ // Or user did something like: press shift, press ctrl, release shift
+ return false;
+ }
+ // Mask up event often generates things like 'shift key + shift mask', filter it out.
+ if (key == KEY_CONTROL)
+ {
+ mask &= ~MASK_CONTROL;
+ }
+ if (key == KEY_SHIFT)
+ {
+ mask &= ~MASK_SHIFT;
+ }
+ if (key == KEY_ALT)
+ {
+ mask &= ~MASK_ALT;
+ }
+ }
+ if ((mKeyFilterMask & ALLOW_KEYS) == 0)
+ {
+ // basic keys not allowed
+ return false;
+ }
+ else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0)
+ {
+ // masked keys not allowed
+ return false;
+ }
+
+ if (LLKeyConflictHandler::isReservedByMenu(key, mask))
+ {
+ pDesription->setText(getString("reserved_by_menu"));
+ pDesription->setTextArg("[KEYSTR]", LLKeyboard::stringFromAccelerator(mask,key));
+ mLastMaskKey = 0;
+ return true;
+ }
+
+ setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean());
+ // Note/Todo: To warranty zero interference we should also consume
+ // an 'up' event if we recorded on 'down', not just close floater
+ // on first recorded combination.
+ sRecordKeys = false;
+ closeFloater();
+ return true;
+}
+
+BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
+{
+ BOOL result = FALSE;
+ if (!pParent)
+ {
+ // we already processed 'down' event, this is 'up', consume
+ closeFloater();
+ result = TRUE;
+ }
+ if (!result && clicktype == CLICK_LEFT)
+ {
+ // try handling buttons first
+ if (down)
+ {
+ result = LLView::handleMouseDown(x, y, mask);
+ }
+ else
+ {
+ result = LLView::handleMouseUp(x, y, mask);
+ }
+ if (result)
+ {
+ setFocus(TRUE);
+ gFocusMgr.setKeystrokesOnly(TRUE);
+ }
+ // ignore selection related combinations
+ else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0)
+ {
+ // this can be a double click, wait a bit;
+ if (!pUpdater)
+ {
+ // Note: default doubleclick time is 500ms, but can stretch up to 5s
+ pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask);
+ result = TRUE;
+ }
+ }
+ }
+
+ if (!result
+ && (clicktype != CLICK_LEFT) // subcases were handled above
+ && ((mKeyFilterMask & ALLOW_MOUSE) != 0)
+ && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported
+ && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection
+ {
+ setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean());
+ result = TRUE;
+ if (!down)
+ {
+ // wait for 'up' event before closing
+ // alternative: set pUpdater
+ closeFloater();
+ }
+ }
+
+ return result;
+}
+
+//static
+void LLSetKeyBindDialog::onCancel(void* user_data)
+{
+ LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+ self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onBlank(void* user_data)
+{
+ LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+ // tmp needs 'no key' button
+ self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);
+ self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onDefault(void* user_data)
+{
+ LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+ if (self->pParent)
+ {
+ self->pParent->onDefaultKeyBind(self->pCheckBox->getValue().asBoolean());
+ self->pParent = NULL;
+ }
+ self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask)
+{
+ LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+
+ // timer will delete itself after timeout
+ self->pUpdater = NULL;
+
+ self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean());
+ self->closeFloater();
+}
+
+void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
+{
+ if (pParent)
+ {
+ pParent->onSetKeyBind(click, key, mask, all_modes);
+ pParent = NULL;
+ }
+}
+
diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h
new file mode 100644
index 0000000000..a34b952233
--- /dev/null
+++ b/indra/newview/llsetkeybinddialog.h
@@ -0,0 +1,106 @@
+/**
+ * @file llsetkeybinddialog.h
+ * @brief LLSetKeyBindDialog class definition
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+
+#ifndef LL_LLSETKEYBINDDIALOG_H
+#define LL_LLSETKEYBINDDIALOG_H
+
+#include "llmodaldialog.h"
+
+class LLCheckBoxCtrl;
+class LLTextBase;
+
+// Filters for LLSetKeyBindDialog
+static const U32 ALLOW_MOUSE = 1;
+static const U32 ALLOW_MASK_MOUSE = 2;
+static const U32 ALLOW_KEYS = 4; //keyboard
+static const U32 ALLOW_MASK_KEYS = 8;
+static const U32 ALLOW_MASKS = 16;
+static const U32 DEFAULT_KEY_FILTER = ALLOW_MOUSE | ALLOW_MASK_MOUSE | ALLOW_KEYS | ALLOW_MASKS | ALLOW_MASK_KEYS;
+
+
+class LLKeyBindResponderInterface
+{
+public:
+ virtual ~LLKeyBindResponderInterface() {};
+
+ virtual void onCancelKeyBind() = 0;
+ virtual void onDefaultKeyBind(bool all_modes) = 0;
+ // returns true if parent failed to set key due to key being in use
+ virtual bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes) = 0;
+};
+
+class LLSetKeyBindDialog : public LLModalDialog
+{
+public:
+ LLSetKeyBindDialog(const LLSD& key);
+ ~LLSetKeyBindDialog();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& data);
+ /*virtual*/ void onClose(bool app_quiting);
+ /*virtual*/ void draw();
+
+ void setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask = DEFAULT_KEY_FILTER);
+
+ // Wrapper around recordAndHandleKey
+ // It does not record, it handles, but handleKey function is already in use
+ static bool recordKey(KEY key, MASK mask, BOOL down);
+
+ BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
+ static void onCancel(void* user_data);
+ static void onBlank(void* user_data);
+ static void onDefault(void* user_data);
+ static void onClickTimeout(void* user_data, MASK mask);
+
+ class Updater;
+
+private:
+ bool recordAndHandleKey(KEY key, MASK mask, BOOL down);
+ void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes);
+ LLKeyBindResponderInterface *pParent;
+ LLCheckBoxCtrl *pCheckBox;
+ LLTextBase *pDesription;
+
+ U32 mKeyFilterMask;
+ Updater *pUpdater;
+ KEY mLastMaskKey;
+
+ static bool sRecordKeys; // for convinience and not to check instance each time
+
+ // drawFrustum
+private:
+ void drawFrustum();
+
+ LLHandle <LLView> mFrustumOrigin;
+ F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
+};
+
+
+#endif // LL_LLSETKEYBINDDIALOG_H
diff --git a/indra/newview/llsettingspicker.cpp b/indra/newview/llsettingspicker.cpp
new file mode 100644
index 0000000000..d2d21063e7
--- /dev/null
+++ b/indra/newview/llsettingspicker.cpp
@@ -0,0 +1,509 @@
+/**
+* @author Rider Linden
+* @brief LLSettingsPicker class header file including related functions
+*
+* $LicenseInfo:firstyear=2018&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2018, 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 "llsettingspicker.h"
+
+#include "llcombobox.h"
+#include "llfiltereditor.h"
+#include "llfolderviewmodel.h"
+#include "llinventory.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
+#include "llsettingsvo.h"
+
+#include "lldraghandle.h"
+#include "llviewercontrol.h"
+#include "llagent.h"
+
+//=========================================================================
+namespace
+{
+ const std::string FLOATER_DEFINITION_XML("floater_settings_picker.xml");
+
+ const std::string FLT_INVENTORY_SEARCH("flt_inventory_search");
+ const std::string CMB_TRACK_SELECTION("track_selection");
+ const std::string PNL_INVENTORY("pnl_inventory");
+ const std::string PNL_COMBO("pnl_combo");
+ const std::string BTN_SELECT("btn_select");
+ const std::string BTN_CANCEL("btn_cancel");
+
+ // strings in xml
+
+ const std::string STR_TITLE_PREFIX = "pick title";
+ const std::string STR_TITLE_TRACK = "pick_track";
+ const std::string STR_TITLE_SETTINGS = "pick_settings";
+ const std::string STR_TRACK_WATER = "track_water";
+ const std::string STR_TRACK_GROUND = "track_ground";
+ const std::string STR_TRACK_SKY = "track_sky";
+}
+//=========================================================================
+
+LLFloaterSettingsPicker::LLFloaterSettingsPicker(LLView * owner, LLUUID initial_item_id, const LLSD &params):
+ LLFloater(params),
+ mOwnerHandle(),
+ mActive(true),
+ mContextConeOpacity(0.0f),
+ mSettingItemID(initial_item_id),
+ mTrackMode(TRACK_NONE),
+ mImmediateFilterPermMask(PERM_NONE)
+{
+ mOwnerHandle = owner->getHandle();
+
+ buildFromFile(FLOATER_DEFINITION_XML);
+ setCanMinimize(FALSE);
+}
+
+
+LLFloaterSettingsPicker::~LLFloaterSettingsPicker()
+{
+
+}
+
+//-------------------------------------------------------------------------
+BOOL LLFloaterSettingsPicker::postBuild()
+{
+ if (!LLFloater::postBuild())
+ return FALSE;
+
+ std::string prefix = getString(STR_TITLE_PREFIX);
+ std::string label = getString(STR_TITLE_SETTINGS);
+ setTitle(prefix + " " + label);
+
+ mFilterEdit = getChild<LLFilterEditor>(FLT_INVENTORY_SEARCH);
+ mFilterEdit->setCommitCallback([this](LLUICtrl*, const LLSD& param){ onFilterEdit(param.asString()); });
+
+ mInventoryPanel = getChild<LLInventoryPanel>(PNL_INVENTORY);
+ if (mInventoryPanel)
+ {
+ U32 filter_types = 0x0;
+ filter_types |= 0x1 << LLInventoryType::IT_SETTINGS;
+
+ mInventoryPanel->setFilterTypes(filter_types);
+ mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
+
+ mInventoryPanel->setSelectCallback([this](const LLFloaterSettingsPicker::itemlist_t &items, bool useraction){ onSelectionChange(items, useraction); });
+ mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ mInventoryPanel->setSuppressOpenItemAction(true);
+
+ // Disable auto selecting first filtered item because it takes away
+ // selection from the item set by LLTextureCtrl owning this floater.
+ mInventoryPanel->getRootFolder()->setAutoSelectOverride(TRUE);
+
+ // don't put keyboard focus on selected item, because the selection callback
+ // will assume that this was user input
+ if (!mSettingItemID.isNull())
+ {
+ //todo: this is bad idea
+ mInventoryPanel->setSelection(mSettingItemID, TAKE_FOCUS_NO);
+ }
+ getChild<LLView>(BTN_SELECT)->setEnabled(mSettingItemID.notNull());
+ }
+
+ mNoCopySettingsSelected = FALSE;
+
+ childSetAction(BTN_CANCEL, [this](LLUICtrl*, const LLSD& param){ onButtonCancel(); });
+ childSetAction(BTN_SELECT, [this](LLUICtrl*, const LLSD& param){ onButtonSelect(); });
+
+ getChild<LLPanel>(PNL_COMBO)->setVisible(mTrackMode != TRACK_NONE);
+
+ // update permission filter once UI is fully initialized
+ mSavedFolderState.setApply(FALSE);
+
+ return TRUE;
+}
+
+void LLFloaterSettingsPicker::onClose(bool app_quitting)
+{
+ if (app_quitting)
+ return;
+
+ mCloseSignal();
+ LLView *owner = mOwnerHandle.get();
+ if (owner)
+ {
+ owner->setFocus(TRUE);
+ }
+ mSettingItemID.setNull();
+ mInventoryPanel->getRootFolder()->clearSelection();
+}
+
+void LLFloaterSettingsPicker::setValue(const LLSD& value)
+{
+ mSettingItemID = value.asUUID();
+}
+
+LLSD LLFloaterSettingsPicker::getValue() const
+{
+ return LLSD(mSettingItemID);
+}
+
+void LLFloaterSettingsPicker::setSettingsFilter(LLSettingsType::type_e type)
+{
+ U64 filter = 0xFFFFFFFFFFFFFFFF;
+ if (type != LLSettingsType::ST_NONE)
+ {
+ filter = static_cast<S64>(0x1) << static_cast<S64>(type);
+ }
+
+ mInventoryPanel->setFilterSettingsTypes(filter);
+}
+
+void LLFloaterSettingsPicker::setTrackMode(ETrackMode mode)
+{
+ mTrackMode = mode;
+ getChild<LLPanel>(PNL_COMBO)->setVisible(mode != TRACK_NONE);
+
+ std::string prefix = getString(STR_TITLE_PREFIX);
+ std::string label;
+ if (mode != TRACK_NONE)
+ {
+ label = getString(STR_TITLE_TRACK);
+ }
+ else
+ {
+ label = getString(STR_TITLE_SETTINGS);
+ }
+ setTitle(prefix + " " + label);
+}
+
+void LLFloaterSettingsPicker::draw()
+{
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+
+//=========================================================================
+void LLFloaterSettingsPicker::onFilterEdit(const std::string& search_string)
+{
+ std::string upper_case_search_string = search_string;
+ LLStringUtil::toUpper(upper_case_search_string);
+
+ if (upper_case_search_string.empty())
+ {
+ if (mInventoryPanel->getFilterSubString().empty())
+ {
+ // current filter and new filter empty, do nothing
+ return;
+ }
+
+ mSavedFolderState.setApply(TRUE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ // add folder with current item to list of previously opened folders
+ LLOpenFoldersWithSelection opener;
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
+ mInventoryPanel->getRootFolder()->scrollToShowSelection();
+
+ }
+ else if (mInventoryPanel->getFilterSubString().empty())
+ {
+ // first letter in search term, save existing folder open state
+ if (!mInventoryPanel->getFilter().isNotDefault())
+ {
+ mSavedFolderState.setApply(FALSE);
+ mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ }
+ }
+
+ mInventoryPanel->setFilterSubString(search_string);
+}
+
+void LLFloaterSettingsPicker::onSelectionChange(const LLFloaterSettingsPicker::itemlist_t &items, bool user_action)
+{
+ bool is_item = false;
+ LLUUID asset_id;
+ if (items.size())
+ {
+ LLFolderViewItem* first_item = items.front();
+
+ mNoCopySettingsSelected = false;
+ if (first_item)
+ {
+ LLItemBridge *bridge_model = dynamic_cast<LLItemBridge *>(first_item->getViewModelItem());
+ if (bridge_model && bridge_model->getItem())
+ {
+ if (!bridge_model->isItemCopyable())
+ {
+ mNoCopySettingsSelected = true;
+ }
+ setSettingsItemId(bridge_model->getItem()->getUUID(), false);
+ asset_id = bridge_model->getItem()->getAssetUUID();
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+ is_item = true;
+
+ if (user_action)
+ {
+ mChangeIDSignal(mSettingItemID);
+ }
+ }
+ }
+ }
+ bool track_picker_enabled = mTrackMode != TRACK_NONE;
+
+ getChild<LLView>(CMB_TRACK_SELECTION)->setEnabled(is_item && track_picker_enabled && mSettingAssetID == asset_id);
+ getChild<LLView>(BTN_SELECT)->setEnabled(is_item && (!track_picker_enabled || mSettingAssetID == asset_id));
+ if (track_picker_enabled && asset_id.notNull() && mSettingAssetID != asset_id)
+ {
+ LLUUID item_id = mSettingItemID;
+ LLHandle<LLFloater> handle = getHandle();
+ LLSettingsVOBase::getSettingsAsset(asset_id,
+ [item_id, handle](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { LLFloaterSettingsPicker::onAssetLoadedCb(handle, item_id, asset_id, settings, status); });
+ }
+}
+
+void LLFloaterSettingsPicker::onAssetLoadedCb(LLHandle<LLFloater> handle, LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+ if (handle.isDead() || status)
+ {
+ return;
+ }
+
+ LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(handle.get());
+
+ if (picker->mSettingItemID != item_id)
+ {
+ return;
+ }
+
+ picker->onAssetLoaded(asset_id, settings);
+}
+
+void LLFloaterSettingsPicker::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings)
+{
+ LLComboBox* track_selection = getChild<LLComboBox>(CMB_TRACK_SELECTION);
+ track_selection->clear();
+ track_selection->removeall();
+ if (!settings)
+ {
+ LL_WARNS() << "Failed to load asset " << asset_id << LL_ENDL;
+ return;
+ }
+ LLSettingsDay::ptr_t pday = std::dynamic_pointer_cast<LLSettingsDay>(settings);
+
+ if (!pday)
+ {
+ LL_WARNS() << "Wrong asset type received by id " << asset_id << LL_ENDL;
+ return;
+ }
+
+ if (mTrackMode == TRACK_WATER)
+ {
+ track_selection->add(getString(STR_TRACK_WATER), LLSD::Integer(LLSettingsDay::TRACK_WATER), ADD_TOP, true);
+ }
+ else if (mTrackMode == TRACK_SKY)
+ {
+ // track 1 always present
+ track_selection->add(getString(STR_TRACK_GROUND), LLSD::Integer(LLSettingsDay::TRACK_GROUND_LEVEL), ADD_TOP, true);
+ LLUIString formatted_label = getString(STR_TRACK_SKY);
+ for (int i = 2; i < LLSettingsDay::TRACK_MAX; i++)
+ {
+ if (!pday->isTrackEmpty(i))
+ {
+ formatted_label.setArg("[NUM]", llformat("%d", i));
+ track_selection->add(formatted_label.getString(), LLSD::Integer(i), ADD_TOP, true);
+ }
+ }
+ }
+
+ mSettingAssetID = asset_id;
+ track_selection->setEnabled(true);
+ track_selection->selectFirstItem();
+ getChild<LLView>(BTN_SELECT)->setEnabled(true);
+}
+
+void LLFloaterSettingsPicker::onButtonCancel()
+{
+ closeFloater();
+}
+
+void LLFloaterSettingsPicker::onButtonSelect()
+{
+ if (mCommitSignal)
+ {
+ LLSD res;
+ res["ItemId"] = mSettingItemID;
+ res["Track"] = getChild<LLComboBox>(CMB_TRACK_SELECTION)->getValue();
+ (*mCommitSignal)(this, res);
+ }
+ closeFloater();
+}
+
+BOOL LLFloaterSettingsPicker::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ BOOL result = FALSE;
+ if (mSettingItemID.notNull()
+ && mInventoryPanel)
+ {
+ S32 inventory_x = x - mInventoryPanel->getRect().mLeft;
+ S32 inventory_y = y - mInventoryPanel->getRect().mBottom;
+ if (mInventoryPanel->parentPointInView(inventory_x, inventory_y))
+ {
+ // make sure item is selected and visible
+ LLFolderViewItem* item_viewp = mInventoryPanel->getItemByID(mSettingItemID);
+ if (item_viewp && item_viewp->getIsCurSelection() && item_viewp->getVisible())
+ {
+ LLRect target_rect;
+ item_viewp->localRectToOtherView(item_viewp->getLocalRect(), &target_rect, this);
+ if (target_rect.pointInRect(x, y))
+ {
+ // Quick-apply
+ if (mCommitSignal)
+ {
+ LLSD res;
+ res["ItemId"] = mSettingItemID;
+ res["Track"] = getChild<LLComboBox>(CMB_TRACK_SELECTION)->getValue();
+ (*mCommitSignal)(this, res);
+ }
+ closeFloater();
+ // hit inside panel on selected item, double click should do nothing
+ result = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!result)
+ {
+ result = LLFloater::handleDoubleClick(x, y, mask);
+ }
+ return result;
+}
+
+BOOL LLFloaterSettingsPicker::handleKeyHere(KEY key, MASK mask)
+{
+ if ((key == KEY_RETURN) && (mask == MASK_NONE))
+ {
+ LLFolderViewItem* item_viewp = mInventoryPanel->getItemByID(mSettingItemID);
+ if (item_viewp && item_viewp->getIsCurSelection() && item_viewp->getVisible())
+ {
+ // Quick-apply
+ if (mCommitSignal)
+ {
+ LLSD res;
+ res["ItemId"] = mSettingItemID;
+ res["Track"] = getChild<LLComboBox>(CMB_TRACK_SELECTION)->getValue();
+ (*mCommitSignal)(this, res);
+ }
+ closeFloater();
+ return TRUE;
+ }
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+}
+
+void LLFloaterSettingsPicker::onFocusLost()
+{
+ if (isInVisibleChain())
+ {
+ closeFloater();
+ }
+}
+
+//=========================================================================
+void LLFloaterSettingsPicker::setActive(bool active)
+{
+ mActive = active;
+}
+
+void LLFloaterSettingsPicker::setSettingsItemId(const LLUUID &settings_id, bool set_selection)
+{
+ if (mSettingItemID != settings_id && mActive)
+ {
+ mNoCopySettingsSelected = false;
+ mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
+ mSettingItemID = settings_id;
+ if (mSettingItemID.isNull())
+ {
+ mInventoryPanel->getRootFolder()->clearSelection();
+ }
+ else
+ {
+ LLInventoryItem* itemp = gInventory.getItem(settings_id);
+ if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
+ {
+ mNoCopySettingsSelected = true;
+ }
+ }
+
+ if (set_selection)
+ {
+ mInventoryPanel->setSelection(settings_id, TAKE_FOCUS_NO);
+ }
+ }
+}
+
+LLInventoryItem* LLFloaterSettingsPicker::findItem(const LLUUID& asset_id, bool copyable_only, bool ignore_library)
+{
+ 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);
+
+ if (items.size())
+ {
+ // search for copyable version first
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLInventoryItem* itemp = items[i];
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return itemp;
+ }
+ }
+ }
+ // otherwise just return first instance, unless copyable requested
+ if (copyable_only)
+ {
+ return nullptr;
+ }
+ else
+ {
+ if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID()))
+ {
+ return items[0];
+ }
+ }
+ }
+
+ return nullptr;
+}
diff --git a/indra/newview/llsettingspicker.h b/indra/newview/llsettingspicker.h
new file mode 100644
index 0000000000..859f92fbe8
--- /dev/null
+++ b/indra/newview/llsettingspicker.h
@@ -0,0 +1,137 @@
+/**
+ * @file llsettingspicker.h
+ * @author Rider Linden
+ * @brief LLSettingsPicker class header file including related functions
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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_SETTINGSPICKER_H
+#define LL_SETTINGSPICKER_H
+
+#include "llinventorysettings.h"
+#include "llfloater.h"
+#include "llpermissionsflags.h"
+#include "llfolderview.h"
+#include "llinventory.h"
+#include "llsettingsdaycycle.h"
+
+#include <boost/signals2.hpp>
+
+//=========================================================================
+class LLFilterEditor;
+class LLInventoryPanel;
+
+//=========================================================================
+class LLFloaterSettingsPicker : public LLFloater
+{
+public:
+ enum ETrackMode
+ {
+ TRACK_NONE,
+ TRACK_WATER,
+ TRACK_SKY
+ };
+ typedef std::function<void()> close_callback_t;
+ typedef std::function<void(const LLUUID& item_id)> id_changed_callback_t;
+
+ LLFloaterSettingsPicker(LLView * owner, LLUUID setting_item_id, const LLSD &params = LLSD());
+
+ virtual ~LLFloaterSettingsPicker() override;
+
+ void setActive(bool active);
+
+ virtual BOOL postBuild() override;
+ virtual void onClose(bool app_quitting) override;
+ virtual void draw() override;
+
+ void setSettingsItemId(const LLUUID &settings_id, bool set_selection = true);
+ LLUUID getSettingsItemId() const { return mSettingItemID; }
+
+ void setSettingsFilter(LLSettingsType::type_e type);
+ LLSettingsType::type_e getSettingsFilter() const { return mSettingsType; }
+
+ // Only for day cycle
+ void setTrackMode(ETrackMode mode);
+ void setTrackWater() { mTrackMode = TRACK_WATER; }
+ void setTrackSky() { mTrackMode = TRACK_SKY; }
+
+ // Takes a UUID, wraps get/setImageAssetID
+ virtual void setValue(const LLSD& value) override;
+ virtual LLSD getValue() const override;
+
+ static LLUUID findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false)
+ {
+ LLInventoryItem *pitem = findItem(asset_id, copyable_only, ignore_library);
+ if (pitem)
+ return pitem->getUUID();
+ return LLUUID::null;
+ }
+
+ static std::string findItemName(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false)
+ {
+ LLInventoryItem *pitem = findItem(asset_id, copyable_only, ignore_library);
+ if (pitem)
+ return pitem->getName();
+ return std::string();
+ }
+
+ static LLInventoryItem * findItem(const LLUUID& asset_id, bool copyable_only, bool ignore_library);
+
+
+private:
+ typedef std::deque<LLFolderViewItem *> itemlist_t;
+
+ void onFilterEdit(const std::string& search_string);
+ void onSelectionChange(const itemlist_t &items, bool user_action);
+ static void onAssetLoadedCb(LLHandle<LLFloater> handle, LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
+ void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings);
+ void onButtonCancel();
+ void onButtonSelect();
+ virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override;
+ BOOL handleKeyHere(KEY key, MASK mask) override;
+ void onFocusLost() override;
+
+
+ LLHandle<LLView> mOwnerHandle;
+ LLUUID mSettingItemID;
+ LLUUID mSettingAssetID;
+ ETrackMode mTrackMode;
+
+ LLFilterEditor * mFilterEdit;
+ LLInventoryPanel * mInventoryPanel;
+ LLSettingsType::type_e mSettingsType;
+
+ F32 mContextConeOpacity;
+ PermissionMask mImmediateFilterPermMask;
+
+ bool mActive;
+ bool mNoCopySettingsSelected;
+
+ LLSaveFolderState mSavedFolderState;
+
+// boost::signals2::signal<void(LLUUID id)> mCommitSignal;
+ boost::signals2::signal<void()> mCloseSignal;
+ boost::signals2::signal<void(const LLUUID& item_id)> mChangeIDSignal;
+};
+
+#endif // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
new file mode 100644
index 0000000000..1e5b893cbc
--- /dev/null
+++ b/indra/newview/llsettingsvo.cpp
@@ -0,0 +1,1462 @@
+/**
+* @file llsettingsvo.cpp
+* @author Rider Linden
+* @brief Subclasses for viewer specific settings behaviors.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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 "llviewercontrol.h"
+#include "llsettingsvo.h"
+
+#include "pipeline.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <boost/make_shared.hpp>
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "v3colorutil.h"
+
+#include "llglslshader.h"
+#include "llviewershadermgr.h"
+
+#include "llagent.h"
+#include "llassettype.h"
+#include "llfloaterperms.h"
+#include "llnotificationsutil.h"
+
+#include "llviewerregion.h"
+#include "llviewerassetupload.h"
+#include "llviewerinventory.h"
+
+#include "llenvironment.h"
+#include "llsky.h"
+
+#include "llpermissions.h"
+
+#include "llinventorymodel.h"
+#include "llassetstorage.h"
+#include "llvfile.h"
+#include "lldrawpoolwater.h"
+
+#include <boost/algorithm/string/replace.hpp>
+#include "llinventoryobserver.h"
+#include "llinventorydefines.h"
+
+#include "lltrans.h"
+
+#undef VERIFY_LEGACY_CONVERSION
+
+//=========================================================================
+namespace
+{
+ LLSD ensure_array_4(LLSD in, F32 fill);
+ LLSD read_legacy_preset_data(const std::string &name, const std::string& path, LLSD &messages);
+
+ //-------------------------------------------------------------------------
+ class LLSettingsInventoryCB : public LLInventoryCallback
+ {
+ public:
+ typedef std::function<void(const LLUUID &)> callback_t;
+
+ LLSettingsInventoryCB(callback_t cbfn) :
+ mCbfn(cbfn)
+ { }
+
+ void fire(const LLUUID& inv_item) override { if (mCbfn) mCbfn(inv_item); }
+
+ private:
+ callback_t mCbfn;
+ };
+
+ //-------------------------------------------------------------------------
+}
+
+
+//=========================================================================
+void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback)
+{
+ LLTransactionID tid;
+ U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings");
+ nextOwnerPerm |= PERM_COPY;
+
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
+ LLNotificationsUtil::add("SettingsUnsuported");
+ return;
+ }
+
+ tid.generate();
+
+ LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([callback](const LLUUID &inventoryId) {
+ LLSettingsVOBase::onInventoryItemCreated(inventoryId, LLSettingsBase::ptr_t(), callback);
+ });
+
+ create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, LLTransactionID::tnull,
+ LLSettingsType::getDefaultName(stype), "",
+ stype, nextOwnerPerm, cb);
+}
+
+
+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();
+ createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback);
+}
+
+void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
+{
+ LLTransactionID tid;
+
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
+ LLNotificationsUtil::add("SettingsUnsuported");
+ return;
+ }
+
+ tid.generate();
+
+ LLPointer<LLInventoryCallback> cb = new LLSettingsInventoryCB([settings, callback](const LLUUID &inventoryId) {
+ LLSettingsVOBase::onInventoryItemCreated(inventoryId, settings, callback);
+ });
+
+ if (settings_name.empty())
+ {
+ settings_name = settings->getName();
+ }
+ create_inventory_settings(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, tid,
+ settings_name, "",
+ settings->getSettingsTypeValue(), next_owner_perm, cb);
+}
+
+void LLSettingsVOBase::onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback)
+{
+ LLViewerInventoryItem *pitem = gInventory.getItem(inventoryId);
+ if (pitem)
+ {
+ LLPermissions perm = pitem->getPermissions();
+ if (perm.getMaskEveryone() != PERM_COPY)
+ {
+ perm.setMaskEveryone(PERM_COPY);
+ pitem->setPermissions(perm);
+ pitem->updateServer(FALSE);
+ }
+ }
+ if (!settings)
+ { // The item was created as new with no settings passed in. Simulator should have given it the default for the type... check ID,
+ // no need to upload asset.
+ LLUUID asset_id;
+ if (pitem)
+ {
+ asset_id = pitem->getAssetUUID();
+ }
+ if (callback)
+ callback(asset_id, inventoryId, LLUUID::null, LLSD());
+ return;
+ }
+ // We need to update some inventory stuff here.... maybe.
+ updateInventoryItem(settings, inventoryId, callback, false);
+}
+
+void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback, bool update_name)
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL;
+ return;
+ }
+
+ std::string agent_url(region->getCapability("UpdateSettingsAgentInventory"));
+
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
+ LLNotificationsUtil::add("SettingsUnsuported");
+ return;
+ }
+
+ LLViewerInventoryItem *inv_item = gInventory.getItem(inv_item_id);
+ if (inv_item)
+ {
+ bool need_update(false);
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
+
+ if (settings->getFlag(LLSettingsBase::FLAG_NOTRANS) && new_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+ {
+ LLPermissions perm(inv_item->getPermissions());
+ perm.setBaseBits(LLUUID::null, FALSE, PERM_TRANSFER);
+ perm.setOwnerBits(LLUUID::null, FALSE, PERM_TRANSFER);
+ new_item->setPermissions(perm);
+ need_update |= true;
+ }
+ if (update_name && (settings->getName() != new_item->getName()))
+ {
+ new_item->rename(settings->getName());
+ settings->setName(new_item->getName()); // account for corrections
+ need_update |= true;
+ }
+ if (need_update)
+ {
+ new_item->updateServer(FALSE);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+ }
+
+ std::stringstream buffer;
+ LLSD settingdata(settings->getSettings());
+ LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
+
+ LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),
+ [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) {
+ LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback);
+ });
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
+}
+
+void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback)
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS("SETTINGS") << "Not connected to a region, cannot save setting." << LL_ENDL;
+ return;
+ }
+
+ std::string agent_url(region->getCapability("UpdateSettingsAgentInventory"));
+
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ LL_WARNS("SETTINGS") << "Region does not support settings inventory objects." << LL_ENDL;
+ LLNotificationsUtil::add("SettingsUnsuported");
+ return;
+ }
+
+ std::stringstream buffer;
+ LLSD settingdata(settings->getSettings());
+
+ LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
+
+ LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),
+ [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) {
+ LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback);
+ });
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
+}
+
+void LLSettingsVOBase::onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback)
+{
+ LL_INFOS("SETTINGS") << "itemId:" << itemId << " newAssetId:" << newAssetId << " newItemId:" << newItemId << " response:" << response << LL_ENDL;
+ psettings->setAssetId(newAssetId);
+ if (callback)
+ callback( newAssetId, itemId, LLUUID::null, response );
+}
+
+void LLSettingsVOBase::onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback)
+{
+ LL_INFOS("SETTINGS") << "Upload to task complete!" << LL_ENDL;
+ psettings->setAssetId(newAssetId);
+ if (callback)
+ callback(newAssetId, itemId, taskId, response);
+}
+
+
+void LLSettingsVOBase::getSettingsAsset(const LLUUID &assetId, LLSettingsVOBase::asset_download_fn callback)
+{
+ gAssetStorage->getAssetData(assetId, LLAssetType::AT_SETTINGS,
+ [callback](LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType, void *, S32 status, LLExtStat ext_status)
+ { onAssetDownloadComplete(vfs, asset_id, status, ext_status, callback); },
+ nullptr, true);
+
+}
+
+void LLSettingsVOBase::onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, LLSettingsVOBase::asset_download_fn callback)
+{
+ LLSettingsBase::ptr_t settings;
+ if (!status)
+ {
+ LLVFile file(vfs, asset_id, LLAssetType::AT_SETTINGS, LLVFile::READ);
+ S32 size = file.getSize();
+
+ std::string buffer(size + 1, '\0');
+ file.read((U8 *)buffer.data(), size);
+
+ std::stringstream llsdstream(buffer);
+ LLSD llsdsettings;
+
+ if (LLSDSerialize::deserialize(llsdsettings, llsdstream, -1))
+ {
+ settings = createFromLLSD(llsdsettings);
+ }
+
+ if (!settings)
+ {
+ status = 1;
+ LL_WARNS("SETTINGS") << "Unable to create settings object." << LL_ENDL;
+ }
+ else
+ {
+ settings->setAssetId(asset_id);
+ }
+ }
+ else
+ {
+ LL_WARNS("SETTINGS") << "Error retrieving asset " << asset_id << ". Status code=" << status << "(" << LLAssetStorage::getErrorString(status) << ") ext_status=" << (U32)ext_status << LL_ENDL;
+ }
+ if (callback)
+ callback(asset_id, settings, status, ext_status);
+}
+
+void LLSettingsVOBase::getSettingsInventory(const LLUUID &inventoryId, inventory_download_fn callback)
+{
+
+}
+
+bool LLSettingsVOBase::exportFile(const LLSettingsBase::ptr_t &settings, const std::string &filename, LLSDSerialize::ELLSD_Serialize format)
+{
+ try
+ {
+ std::ofstream file(filename, std::ios::out | std::ios::trunc);
+ file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
+
+ if (!file)
+ {
+ LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for writing." << LL_ENDL;
+ return false;
+ }
+
+ LLSDSerialize::serialize(settings->getSettings(), file, format);
+ }
+ catch (const std::ios_base::failure &e)
+ {
+ LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+
+LLSettingsBase::ptr_t LLSettingsVOBase::importFile(const std::string &filename)
+{
+ LLSD settings;
+
+ try
+ {
+ std::ifstream file(filename, std::ios::in);
+ file.exceptions(std::ios_base::failbit | std::ios_base::badbit);
+
+ if (!file)
+ {
+ LL_WARNS("SETTINGS") << "Unable to open '" << filename << "' for reading." << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+ }
+
+ if (!LLSDSerialize::deserialize(settings, file, -1))
+ {
+ LL_WARNS("SETTINGS") << "Unable to deserialize settings from '" << filename << "'" << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+ }
+ }
+ catch (const std::ios_base::failure &e)
+ {
+ LL_WARNS("SETTINGS") << "Unable to save settings to file '" << filename << "': " << e.what() << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+ }
+
+ return createFromLLSD(settings);
+}
+
+LLSettingsBase::ptr_t LLSettingsVOBase::createFromLLSD(const LLSD &settings)
+{
+ if (!settings.has(SETTING_TYPE))
+ {
+ LL_WARNS("SETTINGS") << "No settings type in LLSD" << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+ }
+
+ std::string settingtype = settings[SETTING_TYPE].asString();
+
+ LLSettingsBase::ptr_t psetting;
+
+ if (settingtype == "water")
+ {
+ return LLSettingsVOWater::buildWater(settings);
+ }
+ else if (settingtype == "sky")
+ {
+ return LLSettingsVOSky::buildSky(settings);
+ }
+ else if (settingtype == "daycycle")
+ {
+ return LLSettingsVODay::buildDay(settings);
+ }
+
+ LL_WARNS("SETTINGS") << "Unable to determine settings type for '" << settingtype << "'." << LL_ENDL;
+ return LLSettingsBase::ptr_t();
+
+}
+
+//=========================================================================
+LLSettingsVOSky::LLSettingsVOSky(const LLSD &data, bool isAdvanced)
+: LLSettingsSky(data)
+, m_isAdvanced(isAdvanced)
+{
+}
+
+LLSettingsVOSky::LLSettingsVOSky()
+: LLSettingsSky()
+, m_isAdvanced(false)
+{
+}
+
+//-------------------------------------------------------------------------
+LLSettingsSky::ptr_t LLSettingsVOSky::buildSky(LLSD settings)
+{
+ LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
+
+ LLSD results = LLSettingsBase::settingValidation(settings, validations);
+
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsSky::ptr_t();
+ }
+
+ return std::make_shared<LLSettingsVOSky>(settings, true);
+}
+
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages)
+{
+
+ LLSD newsettings = LLSettingsSky::translateLegacySettings(oldsettings);
+ if (newsettings.isUndefined())
+ {
+ messages["REASONS"] = LLTrans::getString("SettingTranslateError", LLSDMap("NAME", name));
+ return LLSettingsSky::ptr_t();
+ }
+
+ newsettings[SETTING_NAME] = name;
+
+ LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
+ LLSD results = LLSettingsBase::settingValidation(newsettings, validations);
+ if (!results["success"].asBoolean())
+ {
+ messages["REASONS"] = LLTrans::getString("SettingValidationError", LLSDMap("NAME", name));
+ LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsSky::ptr_t();
+ }
+
+ LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(newsettings);
+
+#ifdef VERIFY_LEGACY_CONVERSION
+ LLSD oldsettings = LLSettingsVOSky::convertToLegacy(skyp, isAdvanced());
+
+ if (!llsd_equals(oldsettings, oldsettings))
+ {
+ LL_WARNS("SKY") << "Conversion to/from legacy does not match!\n"
+ << "Old: " << oldsettings
+ << "new: " << oldsettings << LL_ENDL;
+ }
+
+#endif
+
+ return skyp;
+}
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages)
+{
+ LLSD legacy_data = read_legacy_preset_data(name, path, messages);
+
+ if (!legacy_data)
+ { // messages filled in by read_legacy_preset_data
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+
+ return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
+}
+
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky()
+{
+ static LLSD default_settings;
+
+ if (!default_settings.size())
+ {
+ default_settings = LLSettingsSky::defaults();
+
+ default_settings[SETTING_NAME] = DEFAULT_SETTINGS_NAME;
+
+ LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
+ LLSD results = LLSettingsBase::settingValidation(default_settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsSky::ptr_t();
+ }
+ }
+
+ LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(default_settings);
+ return skyp;
+}
+
+LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() const
+{
+ LLSD settings = cloneSettings();
+ U32 flags = getFlags();
+
+ LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList();
+ LLSD results = LLSettingsBase::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Sky setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsSky::ptr_t();
+ }
+
+ LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings);
+ skyp->setFlags(flags);
+ return skyp;
+}
+
+void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings)
+{
+ // These may need to be inferred from new settings' density profiles
+ // if the legacy settings values are not available.
+ if (settings.has(SETTING_LEGACY_HAZE))
+ {
+ LLSD legacyhaze = settings[SETTING_LEGACY_HAZE];
+
+ // work-around for setter formerly putting ambient values in wrong loc...
+ if (legacyhaze.has(SETTING_AMBIENT))
+ {
+ legacy[SETTING_AMBIENT] = ensure_array_4(legacyhaze[SETTING_AMBIENT], 1.0f);
+ }
+ else if (settings.has(SETTING_AMBIENT))
+ {
+ legacy[SETTING_AMBIENT] = ensure_array_4(settings[SETTING_AMBIENT], 1.0f);
+ }
+
+ legacy[SETTING_BLUE_DENSITY] = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0);
+ legacy[SETTING_BLUE_HORIZON] = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0);
+
+ legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
+
+ legacy[SETTING_HAZE_DENSITY] = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_HAZE_HORIZON] = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f);
+ }
+}
+
+LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isAdvanced)
+{
+ LLSD legacy(LLSD::emptyMap());
+ LLSD settings = psky->getSettings();
+
+ convertAtmosphericsToLegacy(legacy, settings);
+
+ legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0);
+ legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0);
+ legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0);
+ legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0));
+ legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE];
+ legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())))
+ (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
+ legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0);
+ legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f);
+ legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes
+ legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
+
+ LLVector3 dir = psky->getLightDirection();
+
+ F32 phi = asin(dir.mV[2]);
+ F32 cos_phi = cosf(phi);
+ F32 theta = (cos_phi != 0) ? asin(dir.mV[1] / cos_phi) : 0.0f;
+
+ theta = -theta;
+
+ // get angles back into valid ranges for legacy viewer...
+ //
+ while (theta < 0)
+ {
+ theta += F_PI * 2;
+ }
+
+ if (theta > 4 * F_PI)
+ {
+ theta = fmod(theta, 2 * F_PI);
+ }
+
+ while (phi < -F_PI)
+ {
+ phi += 2 * F_PI;
+ }
+
+ if (phi > 3 * F_PI)
+ {
+ phi = F_PI + fmod(phi - F_PI, 2 * F_PI);
+ }
+
+ legacy[SETTING_LEGACY_EAST_ANGLE] = theta;
+ legacy[SETTING_LEGACY_SUN_ANGLE] = phi;
+
+ return legacy;
+}
+
+//-------------------------------------------------------------------------
+void LLSettingsVOSky::updateSettings()
+{
+ LLSettingsSky::updateSettings();
+ LLVector3 sun_direction = getSunDirection();
+ LLVector3 moon_direction = getMoonDirection();
+
+ // Want the dot prod of sun w/ high noon vector (0,0,1), which is just the z component
+ F32 dp = llmax(sun_direction[2], 0.0f); // clamped to 0 when sun is down
+
+ // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
+ // between sunlight and point lights in windlight to normalize point lights.
+ //
+ // After some A/B comparison of relesae vs EEP, tweak to allow strength to fall below 2
+ // at night, for better match. (mSceneLightStrength is a divisor, so lower value means brighter
+ // local lights)
+ F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
+ mSceneLightStrength = 2.0f * (0.75f + sun_dynamic_range * dp);
+
+ gSky.setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
+ gSky.setSunTextures(getSunTextureId(), getNextSunTextureId());
+ gSky.setMoonTextures(getMoonTextureId(), getNextMoonTextureId());
+ gSky.setCloudNoiseTextures(getCloudNoiseTextureId(), getNextCloudNoiseTextureId());
+ gSky.setBloomTextures(getBloomTextureId(), getNextBloomTextureId());
+
+ gSky.setSunScale(getSunScale());
+ gSky.setMoonScale(getMoonScale());
+}
+
+void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
+{
+ LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+
+ LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
+
+ if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
+ {
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ }
+ else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
+ {
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, light_direction.mV);
+
+ // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
+ LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+ LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
+
+ // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+ // Keep in Sync!
+ // * indra\newview\llsettingsvo.cpp
+ // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
+ // * 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, 1, vect_c_p_d1.mV);
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ LLColor4 sunDiffuse = psky->getSunlightColor();
+ LLColor4 moonDiffuse = psky->getMoonlightColor();
+
+ shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, sunDiffuse.mV);
+ shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, moonDiffuse.mV);
+
+ LLColor4 cloud_color(psky->getCloudColor(), 1.0);
+ shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, 1, cloud_color.mV);
+ }
+
+ shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
+
+ LLColor4 ambient(getTotalAmbient());
+ shader->uniform4fv(LLShaderMgr::AMBIENT, 1, ambient.mV);
+
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
+ shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier());
+ shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier());
+
+ F32 g = getGamma();
+ F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ shader->uniform1f(LLShaderMgr::GAMMA, g);
+ shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma);
+}
+
+LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
+{
+ static parammapping_t param_map;
+
+ if (param_map.empty())
+ {
+// LEGACY_ATMOSPHERICS
+
+ // Todo: default 'legacy' values duplicate the ones from functions like getBlueDensity() find a better home for them
+ // There is LLSettingsSky::defaults(), but it doesn't contain everything since it is geared towards creating new settings.
+ param_map[SETTING_AMBIENT] = DefaultParam(LLShaderMgr::AMBIENT, LLColor3(0.25f, 0.25f, 0.25f).getValue());
+ param_map[SETTING_BLUE_DENSITY] = DefaultParam(LLShaderMgr::BLUE_DENSITY, LLColor3(0.2447f, 0.4487f, 0.7599f).getValue());
+ param_map[SETTING_BLUE_HORIZON] = DefaultParam(LLShaderMgr::BLUE_HORIZON, LLColor3(0.4954f, 0.4954f, 0.6399f).getValue());
+ param_map[SETTING_HAZE_DENSITY] = DefaultParam(LLShaderMgr::HAZE_DENSITY, LLSD(0.7f));
+ param_map[SETTING_HAZE_HORIZON] = DefaultParam(LLShaderMgr::HAZE_HORIZON, LLSD(0.19f));
+ param_map[SETTING_DENSITY_MULTIPLIER] = DefaultParam(LLShaderMgr::DENSITY_MULTIPLIER, LLSD(0.0001f));
+ param_map[SETTING_DISTANCE_MULTIPLIER] = DefaultParam(LLShaderMgr::DISTANCE_MULTIPLIER, LLSD(0.8f));
+
+ // Following values are always present, so we can just zero these ones, but used values from defaults()
+ LLSD sky_defaults = LLSettingsSky::defaults();
+
+ param_map[SETTING_CLOUD_POS_DENSITY2] = DefaultParam(LLShaderMgr::CLOUD_POS_DENSITY2, sky_defaults[SETTING_CLOUD_POS_DENSITY2]);
+ param_map[SETTING_CLOUD_SCALE] = DefaultParam(LLShaderMgr::CLOUD_SCALE, sky_defaults[SETTING_CLOUD_SCALE]);
+ param_map[SETTING_CLOUD_SHADOW] = DefaultParam(LLShaderMgr::CLOUD_SHADOW, sky_defaults[SETTING_CLOUD_SHADOW]);
+ param_map[SETTING_CLOUD_VARIANCE] = DefaultParam(LLShaderMgr::CLOUD_VARIANCE, sky_defaults[SETTING_CLOUD_VARIANCE]);
+ param_map[SETTING_GLOW] = DefaultParam(LLShaderMgr::GLOW, sky_defaults[SETTING_GLOW]);
+ param_map[SETTING_MAX_Y] = DefaultParam(LLShaderMgr::MAX_Y, sky_defaults[SETTING_MAX_Y]);
+
+ //param_map[SETTING_SUNLIGHT_COLOR] = DefaultParam(LLShaderMgr::SUNLIGHT_COLOR, sky_defaults[SETTING_SUNLIGHT_COLOR]);
+ //param_map[SETTING_CLOUD_COLOR] = DefaultParam(LLShaderMgr::CLOUD_COLOR, sky_defaults[SETTING_CLOUD_COLOR]);
+
+ param_map[SETTING_MOON_BRIGHTNESS] = DefaultParam(LLShaderMgr::MOON_BRIGHTNESS, sky_defaults[SETTING_MOON_BRIGHTNESS]);
+ param_map[SETTING_SKY_MOISTURE_LEVEL] = DefaultParam(LLShaderMgr::MOISTURE_LEVEL, sky_defaults[SETTING_SKY_MOISTURE_LEVEL]);
+ 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]);
+
+// AdvancedAtmospherics TODO
+// Provide mappings for new shader params here
+ }
+
+ return param_map;
+}
+
+//=========================================================================
+const F32 LLSettingsVOWater::WATER_FOG_LIGHT_CLAMP(0.3f);
+
+//-------------------------------------------------------------------------
+LLSettingsVOWater::LLSettingsVOWater(const LLSD &data) :
+ LLSettingsWater(data)
+{
+
+}
+
+LLSettingsVOWater::LLSettingsVOWater() :
+ LLSettingsWater()
+{
+
+}
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildWater(LLSD settings)
+{
+ LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
+ LLSD results = LLSettingsWater::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Water setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsWater::ptr_t();
+ }
+
+ return std::make_shared<LLSettingsVOWater>(settings);
+}
+
+//-------------------------------------------------------------------------
+LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages)
+{
+ LLSD newsettings(LLSettingsWater::translateLegacySettings(oldsettings));
+ if (newsettings.isUndefined())
+ {
+ messages["REASONS"] = LLTrans::getString("SettingTranslateError", LLSDMap("NAME", name));
+ return LLSettingsWater::ptr_t();
+ }
+
+ newsettings[SETTING_NAME] = name;
+ LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
+ LLSD results = LLSettingsWater::settingValidation(newsettings, validations);
+ if (!results["success"].asBoolean())
+ {
+ messages["REASONS"] = LLTrans::getString("SettingValidationError", name);
+ LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
+ return LLSettingsWater::ptr_t();
+ }
+
+ LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(newsettings);
+
+#ifdef VERIFY_LEGACY_CONVERSION
+ LLSD oldsettings = LLSettingsVOWater::convertToLegacy(waterp);
+
+ if (!llsd_equals(oldsettings, oldsettings))
+ {
+ LL_WARNS("WATER") << "Conversion to/from legacy does not match!\n"
+ << "Old: " << oldsettings
+ << "new: " << oldsettings << LL_ENDL;
+ }
+
+#endif
+ return waterp;
+}
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages)
+{
+ LLSD legacy_data = read_legacy_preset_data(name, path, messages);
+
+ if (!legacy_data)
+ { // messages filled in by read_legacy_preset_data
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+
+ return buildFromLegacyPreset(LLURI::unescape(name), legacy_data, messages);
+}
+
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater()
+{
+ static LLSD default_settings;
+
+ if (!default_settings.size())
+ {
+ default_settings = LLSettingsWater::defaults();
+
+ default_settings[SETTING_NAME] = DEFAULT_SETTINGS_NAME;
+
+ LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
+ LLSD results = LLSettingsWater::settingValidation(default_settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
+ return LLSettingsWater::ptr_t();
+ }
+ }
+
+ LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(default_settings);
+
+ return waterp;
+}
+
+LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() const
+{
+ LLSD settings = cloneSettings();
+ U32 flags = getFlags();
+ LLSettingsWater::validation_list_t validations = LLSettingsWater::validationList();
+ LLSD results = LLSettingsWater::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Water setting validation failed!: " << results << LL_ENDL;
+ return LLSettingsWater::ptr_t();
+ }
+
+ LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings);
+ waterp->setFlags(flags);
+ return waterp;
+}
+
+LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater)
+{
+ LLSD legacy(LLSD::emptyMap());
+ LLSD settings = pwater->getSettings();
+
+ legacy[SETTING_LEGACY_BLUR_MULTIPLIER] = settings[SETTING_BLUR_MULTIPLIER];
+ legacy[SETTING_LEGACY_FOG_COLOR] = ensure_array_4(settings[SETTING_FOG_COLOR], 1.0f);
+ legacy[SETTING_LEGACY_FOG_DENSITY] = settings[SETTING_FOG_DENSITY];
+ legacy[SETTING_LEGACY_FOG_MOD] = settings[SETTING_FOG_MOD];
+ legacy[SETTING_LEGACY_FRESNEL_OFFSET] = settings[SETTING_FRESNEL_OFFSET];
+ legacy[SETTING_LEGACY_FRESNEL_SCALE] = settings[SETTING_FRESNEL_SCALE];
+ legacy[SETTING_LEGACY_NORMAL_MAP] = settings[SETTING_NORMAL_MAP];
+ legacy[SETTING_LEGACY_NORMAL_SCALE] = settings[SETTING_NORMAL_SCALE];
+ legacy[SETTING_LEGACY_SCALE_ABOVE] = settings[SETTING_SCALE_ABOVE];
+ legacy[SETTING_LEGACY_SCALE_BELOW] = settings[SETTING_SCALE_BELOW];
+ legacy[SETTING_LEGACY_WAVE1_DIR] = settings[SETTING_WAVE1_DIR];
+ legacy[SETTING_LEGACY_WAVE2_DIR] = settings[SETTING_WAVE2_DIR];
+
+ return legacy;
+}
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
+{
+ LLGLSLShader *shader = (LLGLSLShader *)ptarget;
+
+ LLEnvironment& env = LLEnvironment::instance();
+
+ if (force || (shader->mShaderGroup == LLGLSLShader::SG_WATER))
+ {
+ F32 water_height = env.getWaterHeight();
+
+ //transform water plane to eye space
+ glh::vec3f norm(0.f, 0.f, 1.f);
+ glh::vec3f p(0.f, 0.f, water_height + 0.1f);
+
+ F32 modelView[16];
+ for (U32 i = 0; i < 16; i++)
+ {
+ modelView[i] = (F32)gGLModelView[i];
+ }
+
+ glh::matrix4f mat(modelView);
+ glh::matrix4f invtrans = mat.inverse().transpose();
+ glh::vec3f enorm;
+ glh::vec3f ep;
+ invtrans.mult_matrix_vec(norm, enorm);
+ enorm.normalize();
+ mat.mult_matrix_vec(p, ep);
+
+ LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, waterPlane.mV);
+
+ LLVector4 light_direction = env.getClampedLightNorm();
+
+ F32 waterFogKS = 1.f / llmax(light_direction.mV[2], WATER_FOG_LIGHT_CLAMP);
+
+ shader->uniform1f(LLShaderMgr::WATER_FOGKS, waterFogKS);
+
+ F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - water_height;
+ bool underwater = (eyedepth <= 0.0f);
+
+ F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater);
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
+
+ LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, 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, 1, light_direction.mV);
+ }
+}
+
+void LLSettingsVOWater::updateSettings()
+{
+ // base class clears dirty flag so as to not trigger recursive update
+ LLSettingsBase::updateSettings();
+
+ LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
+ if (pwaterpool)
+ {
+ pwaterpool->setTransparentTextures(getTransparentTextureID(), getNextTransparentTextureID());
+ pwaterpool->setOpaqueTexture(GetDefaultOpaqueTextureAssetId());
+ pwaterpool->setNormalMaps(getNormalMapID(), getNextNormalMapID());
+ }
+}
+
+LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const
+{
+ static parammapping_t param_map;
+
+ if (param_map.empty())
+ {
+ //LLSD water_defaults = LLSettingsWater::defaults();
+ //param_map[SETTING_FOG_COLOR] = DefaultParam(LLShaderMgr::WATER_FOGCOLOR, water_defaults[SETTING_FOG_COLOR]);
+ // let this get set by LLSettingsVOWater::applySpecial so that it can properly reflect the underwater modifier
+ //param_map[SETTING_FOG_DENSITY] = DefaultParam(LLShaderMgr::WATER_FOGDENSITY, water_defaults[SETTING_FOG_DENSITY]);
+ }
+ return param_map;
+}
+
+//=========================================================================
+LLSettingsVODay::LLSettingsVODay(const LLSD &data):
+ LLSettingsDay(data)
+{}
+
+LLSettingsVODay::LLSettingsVODay():
+ LLSettingsDay()
+{}
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildDay(LLSD settings)
+{
+ LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t pday = std::make_shared<LLSettingsVODay>(settings);
+ if (pday)
+ pday->initialize();
+
+ return pday;
+}
+
+//-------------------------------------------------------------------------
+LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &name, const std::string &path, const LLSD &oldsettings, LLSD &messages)
+{
+ LLSD newsettings(defaults());
+ std::set<std::string> framenames;
+ std::set<std::string> notfound;
+
+ std::string base_path(gDirUtilp->getDirName(path));
+ std::string water_path(base_path);
+ std::string sky_path(base_path);
+
+ gDirUtilp->append(water_path, "water");
+ gDirUtilp->append(sky_path, "skies");
+
+ newsettings[SETTING_NAME] = name;
+
+ LLSD watertrack = LLSDArray(
+ LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
+ (SETTING_KEYNAME, "water:Default"));
+
+ LLSD skytrack = LLSD::emptyArray();
+
+ for (LLSD::array_const_iterator it = oldsettings.beginArray(); it != oldsettings.endArray(); ++it)
+ {
+ std::string framename = (*it)[1].asString();
+ LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
+ (SETTING_KEYNAME, "sky:" + framename);
+ framenames.insert(framename);
+ skytrack.append(entry);
+ }
+
+ newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack);
+
+ LLSD frames(LLSD::emptyMap());
+
+ {
+ LLSettingsWater::ptr_t pwater = LLSettingsVOWater::buildFromLegacyPresetFile("Default", water_path, messages);
+ if (!pwater)
+ { // messages filled in by buildFromLegacyPresetFile
+ return LLSettingsDay::ptr_t();
+ }
+ frames["water:Default"] = pwater->getSettings();
+ }
+
+ for (std::set<std::string>::iterator itn = framenames.begin(); itn != framenames.end(); ++itn)
+ {
+ LLSettingsSky::ptr_t psky = LLSettingsVOSky::buildFromLegacyPresetFile((*itn), sky_path, messages);
+ if (!psky)
+ { // messages filled in by buildFromLegacyPresetFile
+ return LLSettingsDay::ptr_t();
+ }
+ frames["sky:" + (*itn)] = psky->getSettings();
+ }
+
+ newsettings[SETTING_FRAMES] = frames;
+
+ LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(newsettings, validations);
+ if (!results["success"].asBoolean())
+ {
+ messages["REASONS"] = LLTrans::getString("SettingValidationError", LLSDMap("NAME", name));
+ LL_WARNS("SETTINGS") << "Day setting validation failed!: " << results << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings);
+
+#ifdef VERIFY_LEGACY_CONVERSION
+ LLSD testsettings = LLSettingsVODay::convertToLegacy(dayp);
+
+ if (!llsd_equals(oldsettings, testsettings))
+ {
+ LL_WARNS("DAYCYCLE") << "Conversion to/from legacy does not match!\n"
+ << "Old: " << oldsettings
+ << "new: " << testsettings << LL_ENDL;
+ }
+
+#endif
+
+ dayp->initialize();
+
+ return dayp;
+}
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages)
+{
+ LLSD legacy_data = read_legacy_preset_data(name, path, messages);
+
+ if (!legacy_data)
+ { // messages filled in by read_legacy_preset_data
+ LL_WARNS("SETTINGS") << "Could not load legacy Windlight \"" << name << "\" from " << path << LL_ENDL;
+ return ptr_t();
+ }
+ // Name for LLSettingsDay only, path to get related files from filesystem
+ return buildFromLegacyPreset(LLURI::unescape(name), path, legacy_data, messages);
+}
+
+
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regionId, LLSD daycycle, LLSD skydefs, LLSD waterdef)
+{
+ LLSD frames(LLSD::emptyMap());
+
+ for (LLSD::map_iterator itm = skydefs.beginMap(); itm != skydefs.endMap(); ++itm)
+ {
+ std::string newname = "sky:" + (*itm).first;
+ LLSD newsettings = LLSettingsSky::translateLegacySettings((*itm).second);
+
+ newsettings[SETTING_NAME] = newname;
+ frames[newname] = newsettings;
+
+ LL_WARNS("SETTINGS") << "created region sky '" << newname << "'" << LL_ENDL;
+ }
+
+ LLSD watersettings = LLSettingsWater::translateLegacySettings(waterdef);
+ std::string watername = "water:"+ watersettings[SETTING_NAME].asString();
+ watersettings[SETTING_NAME] = watername;
+ frames[watername] = watersettings;
+
+ LLSD watertrack = LLSDArray(
+ LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
+ (SETTING_KEYNAME, watername));
+
+ LLSD skytrack(LLSD::emptyArray());
+ for (LLSD::array_const_iterator it = daycycle.beginArray(); it != daycycle.endArray(); ++it)
+ {
+ LLSD entry = LLSDMap(SETTING_KEYKFRAME, (*it)[0].asReal())
+ (SETTING_KEYNAME, "sky:" + (*it)[1].asString());
+ skytrack.append(entry);
+ }
+
+ LLSD newsettings = LLSDMap
+ ( SETTING_NAME, "Region (legacy)" )
+ ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack))
+ ( SETTING_FRAMES, frames )
+ ( SETTING_TYPE, "daycycle" );
+
+ LLSettingsSky::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(newsettings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Day setting validation failed!:" << results << LL_ENDL;
+ return LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(newsettings);
+
+ if (dayp)
+ {
+ // true for validation - either validate here, or when cloning for floater.
+ dayp->initialize(true);
+ }
+ return dayp;
+}
+
+
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildDefaultDayCycle()
+{
+ static LLSD default_settings;
+
+ if (!default_settings.size())
+ {
+ default_settings = LLSettingsDay::defaults();
+ default_settings[SETTING_NAME] = DEFAULT_SETTINGS_NAME;
+
+ LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(default_settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsDay::ptr_t();
+ }
+ }
+
+ LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(default_settings);
+
+ dayp->initialize();
+ return dayp;
+}
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildFromEnvironmentMessage(LLSD settings)
+{
+ LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings);
+
+ dayp->initialize();
+ return dayp;
+}
+
+
+void LLSettingsVODay::buildFromOtherSetting(LLSettingsBase::ptr_t settings, LLSettingsVODay::asset_built_fn cb)
+{
+ if (settings->getSettingsType() == "daycycle")
+ {
+ if (cb)
+ cb(std::static_pointer_cast<LLSettingsDay>(settings));
+ }
+ else
+ {
+ LLSettingsVOBase::getSettingsAsset(LLSettingsDay::GetDefaultAssetId(),
+ [settings, cb](LLUUID, LLSettingsBase::ptr_t pday, S32, LLExtStat){ combineIntoDayCycle(std::static_pointer_cast<LLSettingsDay>(pday), settings, cb); });
+ }
+}
+
+void LLSettingsVODay::combineIntoDayCycle(LLSettingsDay::ptr_t pday, LLSettingsBase::ptr_t settings, asset_built_fn cb)
+{
+ if (settings->getSettingsType() == "sky")
+ {
+ pday->setName("sky: " + settings->getName());
+ pday->clearCycleTrack(1);
+ pday->setSettingsAtKeyframe(settings, 0.0, 1);
+ }
+ else if (settings->getSettingsType() == "water")
+ {
+ pday->setName("water: " + settings->getName());
+ pday->clearCycleTrack(0);
+ pday->setSettingsAtKeyframe(settings, 0.0, 0);
+ }
+ else
+ {
+ pday.reset();
+ }
+
+ if (cb)
+ cb(pday);
+}
+
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildClone() const
+{
+ LLSD settings = cloneSettings();
+
+ LLSettingsDay::validation_list_t validations = LLSettingsDay::validationList();
+ LLSD results = LLSettingsDay::settingValidation(settings, validations);
+ if (!results["success"].asBoolean())
+ {
+ LL_WARNS("SETTINGS") << "Day setting validation failed!\n" << results << LL_ENDL;
+ LLSettingsDay::ptr_t();
+ }
+
+ LLSettingsDay::ptr_t dayp = std::make_shared<LLSettingsVODay>(settings);
+
+ U32 flags = getFlags();
+ if (flags)
+ dayp->setFlags(flags);
+
+ dayp->initialize();
+ return dayp;
+}
+
+LLSettingsDay::ptr_t LLSettingsVODay::buildDeepCloneAndUncompress() const
+{
+ // no need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD
+ LLSD settings = llsd_clone(mSettings);
+
+ U32 flags = getFlags();
+ LLSettingsDay::ptr_t day_clone = std::make_shared<LLSettingsVODay>(settings);
+
+ for (S32 i = 0; i < LLSettingsDay::TRACK_MAX; ++i)
+ {
+ const LLSettingsDay::CycleTrack_t& track = getCycleTrackConst(i);
+ LLSettingsDay::CycleTrack_t::const_iterator iter = track.begin();
+ while (iter != track.end())
+ {
+ // 'Unpack', usually for editing
+ // - frames 'share' settings multiple times
+ // - settings can reuse LLSDs they were initialized from
+ // We do not want for edited frame to change multiple frames in same track, so do a clone
+ day_clone->setSettingsAtKeyframe(iter->second->buildDerivedClone(), iter->first, i);
+ iter++;
+ }
+ }
+ day_clone->setFlags(flags);
+ return day_clone;
+}
+
+LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
+{
+ CycleTrack_t &trackwater = pday->getCycleTrack(TRACK_WATER);
+
+ LLSettingsWater::ptr_t pwater;
+ if (!trackwater.empty())
+ {
+ pwater = std::static_pointer_cast<LLSettingsWater>((*trackwater.begin()).second);
+ }
+
+ if (!pwater)
+ pwater = LLSettingsVOWater::buildDefaultWater();
+
+ LLSD llsdwater = LLSettingsVOWater::convertToLegacy(pwater);
+
+ CycleTrack_t &tracksky = pday->getCycleTrack(1); // first sky track
+ std::map<std::string, LLSettingsSky::ptr_t> skys;
+
+ LLSD llsdcycle(LLSD::emptyArray());
+
+ for(CycleTrack_t::iterator it = tracksky.begin(); it != tracksky.end(); ++it)
+ {
+ size_t hash = (*it).second->getHash();
+ std::stringstream name;
+
+ name << hash;
+
+ skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second);
+
+ F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first;
+ llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) );
+ }
+
+ LLSD llsdskylist(LLSD::emptyMap());
+
+ for (std::map<std::string, LLSettingsSky::ptr_t>::iterator its = skys.begin(); its != skys.end(); ++its)
+ {
+ LLSD llsdsky = LLSettingsVOSky::convertToLegacy((*its).second, false);
+ llsdsky[SETTING_NAME] = (*its).first;
+
+ llsdskylist[(*its).first] = llsdsky;
+ }
+
+ return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater);
+}
+
+LLSettingsSkyPtr_t LLSettingsVODay::getDefaultSky() const
+{
+ return LLSettingsVOSky::buildDefaultSky();
+}
+
+LLSettingsWaterPtr_t LLSettingsVODay::getDefaultWater() const
+{
+ return LLSettingsVOWater::buildDefaultWater();
+}
+
+LLSettingsSkyPtr_t LLSettingsVODay::buildSky(LLSD settings) const
+{
+ LLSettingsSky::ptr_t skyp = std::make_shared<LLSettingsVOSky>(settings);
+
+ if (skyp->validate())
+ return skyp;
+
+ return LLSettingsSky::ptr_t();
+}
+
+LLSettingsWaterPtr_t LLSettingsVODay::buildWater(LLSD settings) const
+{
+ LLSettingsWater::ptr_t waterp = std::make_shared<LLSettingsVOWater>(settings);
+
+ if (waterp->validate())
+ return waterp;
+
+ return LLSettingsWater::ptr_t();
+}
+
+//=========================================================================
+namespace
+{
+ LLSD ensure_array_4(LLSD in, F32 fill)
+ {
+ if (in.size() >= 4)
+ return in;
+
+ LLSD out(LLSD::emptyArray());
+
+ for (S32 idx = 0; idx < in.size(); ++idx)
+ {
+ out.append(in[idx]);
+ }
+
+ while (out.size() < 4)
+ {
+ out.append(LLSD::Real(fill));
+ }
+ return out;
+ }
+
+ // This is a disturbing hack
+ std::string legacy_name_to_filename(const std::string &name, bool convertdash = false)
+ {
+ std::string fixedname(LLURI::escape(name));
+
+ if (convertdash)
+ boost::algorithm::replace_all(fixedname, "-", "%2D");
+
+ return fixedname;
+ }
+
+ //---------------------------------------------------------------------
+ LLSD read_legacy_preset_data(const std::string &name, const std::string& path, LLSD &messages)
+ {
+ llifstream xml_file;
+
+ std::string full_path(path);
+ std::string full_name(name);
+ full_name += ".xml";
+ gDirUtilp->append(full_path, full_name);
+
+ xml_file.open(full_path.c_str());
+ if (!xml_file)
+ {
+ std::string bad_path(full_path);
+ full_path = path;
+ full_name = legacy_name_to_filename(name);
+ full_name += ".xml";
+ gDirUtilp->append(full_path, full_name);
+
+ LL_INFOS("LEGACYSETTING") << "Could not open \"" << bad_path << "\" trying escaped \"" << full_path << "\"" << LL_ENDL;
+
+ xml_file.open(full_path.c_str());
+ if (!xml_file)
+ {
+ LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL;
+
+ full_path = path;
+ full_name = legacy_name_to_filename(name, true);
+ full_name += ".xml";
+ gDirUtilp->append(full_path, full_name);
+ xml_file.open(full_path.c_str());
+ if (!xml_file)
+ {
+ messages["REASONS"] = LLTrans::getString("SettingImportFileError", LLSDMap("FILE", bad_path));
+ LL_WARNS("LEGACYSETTING") << "Unable to open legacy windlight \"" << name << "\" from " << path << LL_ENDL;
+ return LLSD();
+ }
+ }
+ }
+
+ LLSD params_data;
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ if (parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
+ {
+ xml_file.close();
+ messages["REASONS"] = LLTrans::getString("SettingParseFileError", LLSDMap("FILE", full_path));
+ return LLSD();
+ }
+ xml_file.close();
+
+ return params_data;
+ }
+}
diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h
new file mode 100644
index 0000000000..65136ad2f5
--- /dev/null
+++ b/indra/newview/llsettingsvo.h
@@ -0,0 +1,192 @@
+/**
+* @file llsettingsvo.h
+* @author Rider Linden
+* @brief Subclasses for viewer specific settings behaviors.
+*
+* $LicenseInfo:2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2017, 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_SETTINGS_VO_H
+#define LL_SETTINGS_VO_H
+
+#include "llsettingsbase.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+#include "llsettingsdaycycle.h"
+
+#include "llsdserialize.h"
+
+#include "llextendedstatus.h"
+#include <boost/signals2.hpp>
+
+class LLVFS;
+class LLInventoryItem;
+class LLGLSLShader;
+
+//=========================================================================
+class LLSettingsVOBase : public LLSettingsBase
+{
+public:
+ typedef std::function<void(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status, LLExtStat extstat)> asset_download_fn;
+ typedef std::function<void(LLInventoryItem *inv_item, LLSettingsBase::ptr_t settings, S32 status, LLExtStat extstat)> inventory_download_fn;
+ typedef std::function<void(LLUUID asset_id, LLUUID inventory_id, LLUUID object_id, LLSD results)> inventory_result_fn;
+
+ static void createNewInventoryItem(LLSettingsType::type_e stype, const LLUUID &parent_id, inventory_result_fn callback = inventory_result_fn());
+ static void createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn());
+ static void createInventoryItem(const LLSettingsBase::ptr_t &settings, U32 next_owner_perm, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback = inventory_result_fn());
+
+ static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn(), bool update_name = true);
+ static void updateInventoryItem(const LLSettingsBase::ptr_t &settings, LLUUID object_id, LLUUID inv_item_id, inventory_result_fn callback = inventory_result_fn());
+
+ static void getSettingsAsset(const LLUUID &assetId, asset_download_fn callback);
+ static void getSettingsInventory(const LLUUID &inventoryId, inventory_download_fn callback = inventory_download_fn());
+
+ static bool exportFile(const LLSettingsBase::ptr_t &settings, const std::string &filename, LLSDSerialize::ELLSD_Serialize format = LLSDSerialize::LLSD_NOTATION);
+ static LLSettingsBase::ptr_t importFile(const std::string &filename);
+ static LLSettingsBase::ptr_t createFromLLSD(const LLSD &settings);
+
+private:
+ struct SettingsSaveData
+ {
+ typedef std::shared_ptr<SettingsSaveData> ptr_t;
+ std::string mType;
+ std::string mTempFile;
+ LLSettingsBase::ptr_t mSettings;
+ LLTransactionID mTransId;
+ };
+
+ LLSettingsVOBase() {}
+
+ static void onInventoryItemCreated(const LLUUID &inventoryId, LLSettingsBase::ptr_t settings, inventory_result_fn callback);
+
+ static void onAgentAssetUploadComplete(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback);
+ static void onTaskAssetUploadComplete(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, LLSettingsBase::ptr_t psettings, inventory_result_fn callback);
+
+ static void onAssetDownloadComplete(LLVFS *vfs, const LLUUID &asset_id, S32 status, LLExtStat ext_status, asset_download_fn callback);
+};
+
+//=========================================================================
+class LLSettingsVOSky : public LLSettingsSky
+{
+public:
+ LLSettingsVOSky(const LLSD &data, bool advanced = false);
+
+ static ptr_t buildSky(LLSD settings);
+
+ static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages);
+ static ptr_t buildDefaultSky();
+ virtual ptr_t buildClone() const SETTINGS_OVERRIDE;
+
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages);
+
+ static LLSD convertToLegacy(const ptr_t &, bool isAdvanced);
+
+ bool isAdvanced() const { return m_isAdvanced; }
+
+ virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); }
+
+protected:
+ LLSettingsVOSky();
+
+ // Interpret new settings in terms of old atmospherics params
+ static void convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings);
+
+ virtual void updateSettings() override;
+
+ virtual void applySpecial(void *, bool) override;
+
+ virtual parammapping_t getParameterMap() const override;
+
+ bool m_isAdvanced = false;
+ F32 mSceneLightStrength = 3.0f;
+};
+
+//=========================================================================
+class LLSettingsVOWater : public LLSettingsWater
+{
+public:
+ LLSettingsVOWater(const LLSD &data);
+
+ static ptr_t buildWater(LLSD settings);
+
+ static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages);
+ static ptr_t buildDefaultWater();
+ virtual ptr_t buildClone() const SETTINGS_OVERRIDE;
+
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages);
+
+ static LLSD convertToLegacy(const ptr_t &);
+
+ virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); }
+
+protected:
+ LLSettingsVOWater();
+
+ virtual void updateSettings() override;
+ virtual void applySpecial(void *, bool) override;
+
+ virtual parammapping_t getParameterMap() const override;
+
+
+private:
+ static const F32 WATER_FOG_LIGHT_CLAMP;
+
+};
+
+//=========================================================================
+class LLSettingsVODay : public LLSettingsDay
+{
+public:
+ typedef std::function<void(LLSettingsDay::ptr_t day)> asset_built_fn;
+
+ // Todo: find a way to make this cnstructor private
+ // It shouldn't be used outside shared_prt and LLSettingsVODay
+ // outside of settings only use buildDay(settings)
+ LLSettingsVODay(const LLSD &data);
+
+ static ptr_t buildDay(LLSD settings);
+
+ static ptr_t buildFromLegacyPreset(const std::string &name, const std::string &path, const LLSD &oldsettings, LLSD &messages);
+ static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages);
+ static ptr_t buildFromLegacyMessage(const LLUUID &regionId, LLSD daycycle, LLSD skys, LLSD water);
+ static ptr_t buildDefaultDayCycle();
+ static ptr_t buildFromEnvironmentMessage(LLSD settings);
+ static void buildFromOtherSetting(LLSettingsBase::ptr_t settings, asset_built_fn cb);
+ virtual ptr_t buildClone() const SETTINGS_OVERRIDE;
+ virtual ptr_t buildDeepCloneAndUncompress() const SETTINGS_OVERRIDE;
+
+ static LLSD convertToLegacy(const ptr_t &);
+
+ virtual LLSettingsSkyPtr_t getDefaultSky() const override;
+ virtual LLSettingsWaterPtr_t getDefaultWater() const override;
+ virtual LLSettingsSkyPtr_t buildSky(LLSD) const override;
+ virtual LLSettingsWaterPtr_t buildWater(LLSD) const override;
+
+protected:
+ LLSettingsVODay();
+
+private:
+ static void combineIntoDayCycle(LLSettingsDay::ptr_t, LLSettingsBase::ptr_t, asset_built_fn);
+};
+
+
+#endif
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 6e2b4a00fc..6dfe40c29a 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -140,6 +140,8 @@ BOOL LLSidepanelAppearance::postBuild()
setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2));
+ setWearablesLoading(gAgentWearables.isCOFChangeInProgress());
+
return TRUE;
}
@@ -162,8 +164,12 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
std::string type = key["type"].asString();
if (type == "my_outfits")
{
- showOutfitsInventoryPanel();
+ showOutfitsInventoryPanel("outfitslist_tab");
}
+ else if (type == "now_wearing")
+ {
+ showOutfitsInventoryPanel("cof_tab");
+ }
else if (type == "edit_outfit")
{
showOutfitEditPanel();
@@ -285,7 +291,14 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
{
toggleWearableEditPanel(FALSE);
toggleOutfitEditPanel(FALSE);
- toggleMyOutfitsPanel(TRUE);
+ toggleMyOutfitsPanel(TRUE, "");
+}
+
+void LLSidepanelAppearance::showOutfitsInventoryPanel(const std::string &tab_name)
+{
+ toggleWearableEditPanel(FALSE);
+ toggleOutfitEditPanel(FALSE);
+ toggleMyOutfitsPanel(TRUE, tab_name);
}
void LLSidepanelAppearance::showOutfitEditPanel()
@@ -310,37 +323,42 @@ void LLSidepanelAppearance::showOutfitEditPanel()
return;
}
- toggleMyOutfitsPanel(FALSE);
+ toggleMyOutfitsPanel(FALSE, "");
toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
toggleOutfitEditPanel(TRUE);
}
void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
{
- toggleMyOutfitsPanel(FALSE);
+ toggleMyOutfitsPanel(FALSE, "");
toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
toggleWearableEditPanel(TRUE, wearable, disable_camera_switch);
}
-void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible)
+void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name)
{
- if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible)
- {
- // visibility isn't changing, hence nothing to do
- return;
- }
-
- mPanelOutfitsInventory->setVisible(visible);
-
- // *TODO: Move these controls to panel_outfits_inventory.xml
- // so that we don't need to toggle them explicitly.
- mFilterEditor->setVisible(visible);
- mCurrOutfitPanel->setVisible(visible);
-
- if (visible)
- {
- mPanelOutfitsInventory->onOpen(LLSD());
- }
+ if (!mPanelOutfitsInventory
+ || (mPanelOutfitsInventory->getVisible() == visible && tab_name.empty()))
+ {
+ // visibility isn't changing, hence nothing to do
+ return;
+ }
+
+ mPanelOutfitsInventory->setVisible(visible);
+
+ // *TODO: Move these controls to panel_outfits_inventory.xml
+ // so that we don't need to toggle them explicitly.
+ mFilterEditor->setVisible(visible);
+ mCurrOutfitPanel->setVisible(visible);
+
+ if (visible)
+ {
+ mPanelOutfitsInventory->onOpen(LLSD());
+ if (!tab_name.empty())
+ {
+ mPanelOutfitsInventory->openApearanceTab(tab_name);
+ }
+ }
}
void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch)
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 7817fd317c..bb9709a2b8 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -56,7 +56,8 @@ public:
void fetchInventory();
void inventoryFetched();
- void showOutfitsInventoryPanel();
+ void showOutfitsInventoryPanel(); // last selected
+ void showOutfitsInventoryPanel(const std::string& tab_name);
void showOutfitEditPanel();
void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
void setWearablesLoading(bool val);
@@ -72,7 +73,7 @@ private:
void onOpenOutfitButtonClicked();
void onEditAppearanceButtonClicked();
- void toggleMyOutfitsPanel(BOOL visible);
+ void toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name);
void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index d508621b41..b23e24a222 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -336,6 +336,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
BOOL is_complete = item->isFinished();
const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(item->getInventoryType());
const BOOL is_calling_card = (item->getInventoryType() == LLInventoryType::IT_CALLINGCARD);
+ const BOOL is_settings = (item->getInventoryType() == LLInventoryType::IT_SETTINGS);
const LLPermissions& perm = item->getPermissions();
const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
GP_OBJECT_MANIPULATE);
@@ -665,14 +666,14 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
LLUICtrl* edit_cost = getChild<LLUICtrl>("Edit Cost");
// Check for ability to change values.
- if (is_obj_modify && can_agent_sell
+ if (is_obj_modify && can_agent_sell
&& gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
{
getChildView("CheckPurchase")->setEnabled(is_complete);
getChildView("NextOwnerLabel")->setEnabled(TRUE);
getChildView("CheckNextOwnerModify")->setEnabled((base_mask & PERM_MODIFY) && !cannot_restrict_permissions);
- getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions);
+ getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions && !is_settings);
getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions);
combo_sale_type->setEnabled(is_complete && is_for_sale);
@@ -691,6 +692,25 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
edit_cost->setEnabled(FALSE);
}
+ // Hide any properties that are not relevant to settings
+ if (is_settings)
+ {
+ getChild<LLUICtrl>("GroupLabel")->setEnabled(false);
+ getChild<LLUICtrl>("GroupLabel")->setVisible(false);
+ getChild<LLUICtrl>("CheckShareWithGroup")->setEnabled(false);
+ getChild<LLUICtrl>("CheckShareWithGroup")->setVisible(false);
+ getChild<LLUICtrl>("AnyoneLabel")->setEnabled(false);
+ getChild<LLUICtrl>("AnyoneLabel")->setVisible(false);
+ getChild<LLUICtrl>("CheckEveryoneCopy")->setEnabled(false);
+ getChild<LLUICtrl>("CheckEveryoneCopy")->setVisible(false);
+ getChild<LLUICtrl>("CheckPurchase")->setEnabled(false);
+ getChild<LLUICtrl>("CheckPurchase")->setVisible(false);
+ getChild<LLUICtrl>("ComboBoxSaleType")->setEnabled(false);
+ getChild<LLUICtrl>("ComboBoxSaleType")->setVisible(false);
+ getChild<LLUICtrl>("Edit Cost")->setEnabled(false);
+ getChild<LLUICtrl>("Edit Cost")->setVisible(false);
+ }
+
// Set values.
getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale);
getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index 8e1f80abfc..f325315933 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -34,8 +34,12 @@
#include "llvolume.h"
#include "llrigginginfo.h"
+#define DEBUG_SKINNING LL_DEBUG
+#define MAT_USE_SSE 1
+
void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, const LLMeshSkinInfo *skin)
{
+#if DEBUG_SKINNING
static S32 dump_count = 0;
const S32 max_dump = 10;
@@ -81,12 +85,12 @@ void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, c
dump_count++;
}
+#endif
}
-U32 LLSkinningUtil::getMaxJointCount()
+S32 LLSkinningUtil::getMaxJointCount()
{
- U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT;
- return result;
+ return (S32)LL_MAX_JOINTS_PER_MESH_OBJECT;
}
U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin)
@@ -116,6 +120,8 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
skin->mInvalidJointsScrubbed = true;
}
+#define MAT_USE_SSE 1
+
void LLSkinningUtil::initSkinningMatrixPalette(
LLMatrix4* mat,
S32 count,
@@ -126,9 +132,9 @@ void LLSkinningUtil::initSkinningMatrixPalette(
for (U32 j = 0; j < count; ++j)
{
LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
+ llassert(joint);
if (joint)
{
-#define MAT_USE_SSE
#ifdef MAT_USE_SSE
LLMatrix4a bind, world, res;
bind.loadu(skin->mInvBindMatrix[j]);
@@ -143,6 +149,7 @@ void LLSkinningUtil::initSkinningMatrixPalette(
else
{
mat[j] = skin->mInvBindMatrix[j];
+#if DEBUG_SKINNING
// This shouldn't happen - in mesh upload, skinned
// rendering should be disabled unless all joints are
// valid. In other cases of skinned rendering, invalid
@@ -153,16 +160,15 @@ void LLSkinningUtil::initSkinningMatrixPalette(
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
<< " avatar build state: isBuilt() " << avatar->isBuilt()
<< " mInitFlags " << avatar->mInitFlags << LL_ENDL;
-#if 0
- dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin);
#endif
+ dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin);
}
}
}
void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
{
-#ifdef SHOW_ASSERT // same condition that controls llassert()
+#if DEBUG_SKINNING
const S32 max_joints = skin->mJointNames.size();
for (U32 j=0; j<num_vertices; j++)
{
@@ -261,6 +267,7 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar)
{
for (U32 j = 0; j < skin->mJointNames.size(); ++j)
{
+ #if DEBUG_SKINNING
LLJoint *joint = NULL;
if (skin->mJointNums[j] == -1)
{
@@ -278,11 +285,16 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar)
{
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " unable to find joint " << skin->mJointNames[j] << LL_ENDL;
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " avatar build state: isBuilt() " << avatar->isBuilt() << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
-#if 0
dump_avatar_and_skin_state("initJointNums joint not found", avatar, skin);
-#endif
+ skin->mJointNums[j] = 0;
}
}
+ #else
+ LLJoint *joint = (skin->mJointNums[j] == -1) ? avatar->getJoint(skin->mJointNames[j]) : avatar->getJoint(skin->mJointNums[j]);
+ skin->mJointNums[j] = joint ? joint->getJointNum() : 0;
+ #endif
+ // insure we have *a* valid joint to reference
+ llassert(skin->mJointNums[j] >= 0);
}
skin->mJointNumsInitialized = true;
}
@@ -297,7 +309,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
if (vol_face.mJointRiggingInfoTab.needsUpdate())
{
S32 num_verts = vol_face.mNumVertices;
- if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0))
+ S32 num_joints = skin->mJointNames.size();
+ if (num_verts > 0 && vol_face.mWeights && num_joints > 0)
{
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
if (vol_face.mJointRiggingInfoTab.size()==0)
@@ -331,7 +344,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
for (U32 k=0; k<4; ++k)
{
S32 joint_index = idx[k];
- if (wght[k] > 0.0f)
+ if (wght[k] > 0.0f && num_joints > joint_index)
{
S32 joint_num = skin->mJointNums[joint_index];
if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
@@ -340,14 +353,17 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
// FIXME could precompute these matMuls.
LLMatrix4a bind_shape;
- bind_shape.loadu(skin->mBindShapeMatrix);
LLMatrix4a inv_bind;
- inv_bind.loadu(skin->mInvBindMatrix[joint_index]);
LLMatrix4a mat;
- matMul(bind_shape, inv_bind, mat);
LLVector4a pos_joint_space;
+
+ bind_shape.loadu(skin->mBindShapeMatrix);
+ inv_bind.loadu(skin->mInvBindMatrix[joint_index]);
+ matMul(bind_shape, inv_bind, mat);
+
mat.affineTransform(pos, pos_joint_space);
pos_joint_space.mul(wght[k]);
+
LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents();
update_min_max(extents[0], extents[1], pos_joint_space);
}
@@ -362,6 +378,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
vol_face.mJointRiggingInfoTab.setNeedsUpdate(false);
}
}
+
+#if DEBUG_SKINNING
if (vol_face.mJointRiggingInfoTab.size()!=0)
{
LL_DEBUGS("RigSpammish") << "we have rigging info for vf " << &vol_face
@@ -372,6 +390,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
LL_DEBUGS("RigSpammish") << "no rigging info for vf " << &vol_face
<< " num_verts " << vol_face.mNumVertices << LL_ENDL;
}
+#endif
}
}
diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h
index 2c77e030aa..efe7c85997 100644
--- a/indra/newview/llskinningutil.h
+++ b/indra/newview/llskinningutil.h
@@ -27,20 +27,44 @@
#ifndef LLSKINNINGUTIL_H
#define LLSKINNINGUTIL_H
+#include "v2math.h"
+#include "v4math.h"
+#include "llvector4a.h"
+#include "llmatrix4a.h"
+
class LLVOAvatar;
class LLMeshSkinInfo;
-class LLMatrix4a;
class LLVolumeFace;
+class LLJointRiggingInfoTab;
namespace LLSkinningUtil
{
- U32 getMaxJointCount();
+ S32 getMaxJointCount();
U32 getMeshJointCount(const LLMeshSkinInfo *skin);
void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
+
+ LL_FORCE_INLINE void getPerVertexSkinMatrixWithIndices(
+ F32* weights,
+ U8* idx,
+ LLMatrix4a* mat,
+ LLMatrix4a& final_mat,
+ LLMatrix4a* src)
+ {
+ final_mat.clear();
+ src[0].setMul(mat[idx[0]], weights[0]);
+ src[1].setMul(mat[idx[1]], weights[1]);
+ final_mat.add(src[0]);
+ final_mat.add(src[1]);
+ src[2].setMul(mat[idx[2]], weights[2]);
+ src[3].setMul(mat[idx[3]], weights[3]);
+ final_mat.add(src[2]);
+ final_mat.add(src[3]);
+ }
+
void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar);
void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face);
LLQuaternion getUnscaledQuaternion(const LLMatrix4& mat4);
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index 5e2442798b..ac7dbcacaa 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -51,19 +51,16 @@
#include "llvosky.h"
#include "llcubemap.h"
#include "llviewercontrol.h"
-#include "llenvmanager.h"
-
+#include "llenvironment.h"
+#include "llvoavatarself.h"
#include "llvowlsky.h"
F32 azimuth_from_vector(const LLVector3 &v);
F32 elevation_from_vector(const LLVector3 &v);
-LLSky gSky;
-// ---------------- LLSky ----------------
-
-const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees
-const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD);
+LLSky gSky;
+// ---------------- LLSky ----------------
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -77,8 +74,6 @@ LLSky::LLSky()
mLightingGeneration = 0;
mUpdatedThisFrame = TRUE;
- mOverrideSimSunPosition = FALSE;
- mSunPhase = 0.f;
}
@@ -134,211 +129,89 @@ void LLSky::resetVertexBuffers()
}
}
-void LLSky::setOverrideSun(BOOL override)
+void LLSky::setSunScale(F32 sun_scale)
{
- if (!mOverrideSimSunPosition && override)
- {
- mLastSunDirection = getSunDirection();
- }
- else if (mOverrideSimSunPosition && !override)
- {
- setSunDirection(mLastSunDirection, LLVector3::zero);
+ if(mVOSkyp.notNull())
+ {
+ mVOSkyp->setSunScale(sun_scale);
}
- mOverrideSimSunPosition = override;
}
-void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
+void LLSky::setMoonScale(F32 moon_scale)
{
- if(mVOSkyp.notNull()) {
- mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity);
+ if(mVOSkyp.notNull())
+ {
+ mVOSkyp->setMoonScale(moon_scale);
}
}
-
-void LLSky::setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
-{
- mSunTargDir = sun_direction;
-}
-
-
-LLVector3 LLSky::getSunDirection() const
+void LLSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
{
- if (mVOSkyp)
- {
- return mVOSkyp->getToSun();
- }
- else
- {
- return LLVector3::z_axis;
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setSunTextures(sun_texture, sun_texture_next);
}
}
-
-LLVector3 LLSky::getMoonDirection() const
+void LLSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
{
- if (mVOSkyp)
- {
- return mVOSkyp->getToMoon();
- }
- else
- {
- return LLVector3::z_axis;
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setMoonTextures(moon_texture, moon_texture_next);
}
}
-
-LLColor4 LLSky::getSunDiffuseColor() const
+void LLSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getSunDiffuseColor());
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setCloudNoiseTextures(cloud_noise_texture, cloud_noise_texture_next);
}
}
-LLColor4 LLSky::getSunAmbientColor() const
-{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getSunAmbientColor());
- }
- else
- {
- return LLColor4(0.f, 0.f, 0.f, 1.f);
- }
-}
-
-
-LLColor4 LLSky::getMoonDiffuseColor() const
+void LLSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next)
{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getMoonDiffuseColor());
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
- }
-}
-
-LLColor4 LLSky::getMoonAmbientColor() const
-{
- if (mVOSkyp)
- {
- return LLColor4(mVOSkyp->getMoonAmbientColor());
- }
- else
- {
- return LLColor4(0.f, 0.f, 0.f, 0.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setBloomTextures(bloom_texture, bloom_texture_next);
}
}
-
-LLColor4 LLSky::getTotalAmbientColor() const
+void LLSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction)
{
- if (mVOSkyp)
- {
- return mVOSkyp->getTotalAmbientColor();
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setSunAndMoonDirectionsCFR(sun_direction, moon_direction);
}
}
-
-BOOL LLSky::sunUp() const
+void LLSky::setSunDirectionCFR(const LLVector3 &sun_direction)
{
- if (mVOSkyp)
- {
- return mVOSkyp->isSunUp();
- }
- else
- {
- return TRUE;
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setSunDirectionCFR(sun_direction);
}
}
-
-LLColor4U LLSky::getFadeColor() const
+void LLSky::setMoonDirectionCFR(const LLVector3 &moon_direction)
{
- if (mVOSkyp)
- {
- return mVOSkyp->getFadeColor();
- }
- else
- {
- return LLColor4(1.f, 1.f, 1.f, 1.f);
+ if(mVOSkyp.notNull()) {
+ mVOSkyp->setMoonDirectionCFR(moon_direction);
}
}
-
//////////////////////////////////////////////////////////////////////
// Public Methods
//////////////////////////////////////////////////////////////////////
-void LLSky::init(const LLVector3 &sun_direction)
+void LLSky::init()
{
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, NULL));
- mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero);
+ mVOWLSkyp->init();
gPipeline.createObject(mVOWLSkyp.get());
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, NULL);
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
- mVOSkyp->initSunDirection(sun_direction, LLVector3());
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
- gPipeline.createObject((LLViewerObject *)mVOSkyp);
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ mVOSkyp->init();
+ gPipeline.createObject(mVOSkyp.get());
mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, NULL);
- LLVOGround *groundp = mVOGroundp;
- gPipeline.createObject((LLViewerObject *)groundp);
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
- gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));
-
- ////////////////////////////
- //
- // Legacy code, ignore
- //
- //
-
- // Get the parameters.
- mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition");
-
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
- if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || mOverrideSimSunPosition)
- {
- setSunDirection(mSunDefaultPosition, LLVector3(0.f, 0.f, 0.f));
- }
- else
- {
- setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f));
- }
+ gPipeline.createObject(mVOGroundp.get());
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));
mUpdatedThisFrame = TRUE;
}
@@ -361,37 +234,21 @@ void LLSky::setWind(const LLVector3& average_wind)
}
}
+void LLSky::addSunMoonBeacons()
+{
+ if (!gAgentAvatarp || !mVOSkyp) return;
-void LLSky::propagateHeavenlyBodies(F32 dt)
-{
- if (!mOverrideSimSunPosition)
+ static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
+ static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
+
+ if (show_sun_beacon)
{
- LLVector3 curr_dir = getSunDirection();
- LLVector3 diff = mSunTargDir - curr_dir;
- const F32 dist = diff.normVec();
- if (dist > 0)
- {
- const F32 step = llmin (dist, 0.00005f);
- //const F32 step = min (dist, 0.0001);
- diff *= step;
- curr_dir += diff;
- curr_dir.normVec();
- if (mVOSkyp)
- {
- mVOSkyp->setSunDirection(curr_dir, LLVector3());
- }
- }
+ renderSunMoonBeacons(gAgentAvatarp->getPositionAgent(), mVOSkyp->getSun().getDirection(), LLColor4(1.f, 0.5f, 0.f, 0.5f));
+ }
+ if (show_moon_beacon)
+ {
+ renderSunMoonBeacons(gAgentAvatarp->getPositionAgent(), mVOSkyp->getMoon().getDirection(), LLColor4(1.f, 0.f, 0.8f, 0.5f));
}
-}
-
-F32 LLSky::getSunPhase() const
-{
- return mSunPhase;
-}
-
-void LLSky::setSunPhase(const F32 phase)
-{
- mSunPhase = phase;
}
//////////////////////////////////////////////////////////////////////
@@ -399,11 +256,11 @@ void LLSky::setSunPhase(const F32 phase)
//////////////////////////////////////////////////////////////////////
-LLColor4 LLSky::getFogColor() const
+LLColor4 LLSky::getSkyFogColor() const
{
if (mVOSkyp)
{
- return mVOSkyp->getFogColor();
+ return mVOSkyp->getSkyFogColor();
}
return LLColor4(1.f, 1.f, 1.f, 1.f);
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index 7b98c97840..8c0d70c16c 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -48,16 +48,23 @@ public:
LLSky();
~LLSky();
- void init(const LLVector3 &sun_direction);
-
+ void init();
void cleanup();
- void setOverrideSun(BOOL override);
- BOOL getOverrideSun() { return mOverrideSimSunPosition; }
- void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity);
- void setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity);
+ // These directions should be in CFR coord sys (+x at, +z up, +y right)
+ void setSunAndMoonDirectionsCFR(const LLVector3 &sun_direction, const LLVector3 &moon_direction);
+ void setSunDirectionCFR(const LLVector3 &sun_direction);
+ void setMoonDirectionCFR(const LLVector3 &moon_direction);
+
+ void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
+ void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+ void setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next);
+ void setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next);
- LLColor4 getFogColor() const;
+ void setSunScale(F32 sun_scale);
+ void setMoonScale(F32 moon_scale);
+
+ LLColor4 getSkyFogColor() const;
void setCloudDensityAtAgent(F32 cloud_density);
void setWind(const LLVector3& wind);
@@ -66,8 +73,6 @@ public:
void updateCull();
void updateSky();
- void propagateHeavenlyBodies(F32 dt); // dt = seconds
-
S32 mLightingGeneration;
BOOL mUpdatedThisFrame;
@@ -75,44 +80,21 @@ public:
F32 getFogRatio() const;
LLColor4U getFadeColor() const;
- LLVector3 getSunDirection() const;
- LLVector3 getMoonDirection() const;
- LLColor4 getSunDiffuseColor() const;
- LLColor4 getMoonDiffuseColor() const;
- LLColor4 getSunAmbientColor() const;
- LLColor4 getMoonAmbientColor() const;
- LLColor4 getTotalAmbientColor() const;
- BOOL sunUp() const;
-
- F32 getSunPhase() const;
- void setSunPhase(const F32 phase);
-
void destroyGL();
void restoreGL();
void resetVertexBuffers();
+ void addSunMoonBeacons();
+ void renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color);
+
public:
LLPointer<LLVOSky> mVOSkyp; // Pointer to the LLVOSky object (only one, ever!)
LLPointer<LLVOGround> mVOGroundp;
-
LLPointer<LLVOWLSky> mVOWLSkyp;
- LLVector3 mSunTargDir;
-
- // Legacy stuff
- LLVector3 mSunDefaultPosition;
-
- static const F32 NIGHTTIME_ELEVATION; // degrees
- static const F32 NIGHTTIME_ELEVATION_COS;
-
protected:
- BOOL mOverrideSimSunPosition;
-
- F32 mSunPhase;
- LLColor4 mFogColor; // Color to use for fog and haze
-
- LLVector3 mLastSunDirection;
+ LLColor4 mFogColor;
};
-extern LLSky gSky;
+extern LLSky gSky;
#endif
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 8fef3ff1c0..8369def968 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -28,10 +28,10 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llagentui.h"
#include "llcombobox.h"
-#include "lleconomy.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llimagefilter.h"
@@ -63,6 +63,7 @@ F32 SHINE_WIDTH = 0.6f;
F32 SHINE_OPACITY = 0.3f;
F32 FALL_TIME = 0.6f;
S32 BORDER_WIDTH = 6;
+S32 TOP_PANEL_HEIGHT = 30;
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
@@ -154,7 +155,7 @@ F32 LLSnapshotLivePreview::getImageAspect()
void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)
{
- LL_DEBUGS() << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << LL_ENDL;
// Update snapshot if requested.
if (new_snapshot)
@@ -293,8 +294,8 @@ void LLSnapshotLivePreview::draw()
F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f);
F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f);
gGL.pushMatrix();
- {
- gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
+ {
+ gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom + TOP_PANEL_HEIGHT, 0.f);
gGL.begin(LLRender::QUADS);
{
gGL.texCoord2f(uv_width, uv_height);
@@ -342,18 +343,19 @@ void LLSnapshotLivePreview::draw()
}
else if (mShineAnimTimer.getStarted())
{
- LL_DEBUGS() << "Drawing shining animation" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "Drawing shining animation" << LL_ENDL;
F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
// draw "shine" effect
- LLLocalClipRect clip(getLocalRect());
+ LLRect local_rect(0, getRect().getHeight() + TOP_PANEL_HEIGHT, getRect().getWidth(), 0);
+ LLLocalClipRect clip(local_rect);
{
// draw diagonal stripe with gradient that passes over screen
S32 x1 = gViewerWindow->getWindowWidthScaled() * ll_round((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
S32 x2 = x1 + ll_round(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
S32 x3 = x2 + ll_round(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
S32 y1 = 0;
- S32 y2 = gViewerWindow->getWindowHeightScaled();
+ S32 y2 = gViewerWindow->getWindowHeightScaled() + TOP_PANEL_HEIGHT;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin(LLRender::QUADS);
@@ -383,43 +385,13 @@ void LLSnapshotLivePreview::draw()
}
}
- // draw framing rectangle
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f(1.f, 1.f, 1.f, 1.f);
- const LLRect& outline_rect = getImageRect();
- gGL.begin(LLRender::QUADS);
- {
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
-
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
-
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
-
- gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- }
- gGL.end();
- }
-
// draw old image dropping away
if (mFallAnimTimer.getStarted())
{
S32 old_image_index = (mCurImageIndex + 1) % 2;
if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
{
- LL_DEBUGS() << "Drawing fall animation" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "Drawing fall animation" << LL_ENDL;
F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
LLColor4 image_color(1.f, 1.f, 1.f, alpha);
@@ -463,7 +435,7 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare
LLView::reshape(width, height, called_from_parent);
if (old_rect.getWidth() != width || old_rect.getHeight() != height)
{
- LL_DEBUGS() << "window reshaped, updating thumbnail" << LL_ENDL;
+ LL_DEBUGS("Window", "Snapshot") << "window reshaped, updating thumbnail" << LL_ENDL;
if (mViewContainer && mViewContainer->isInVisibleChain())
{
// We usually resize only on window reshape, so give it a chance to redraw, assign delay
@@ -586,6 +558,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
if(!gViewerWindow->thumbnailSnapshot(raw,
mThumbnailWidth, mThumbnailHeight,
mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
FALSE,
mSnapshotBufferType) )
{
@@ -607,7 +580,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
}
else
{
- LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+ LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
}
}
// Scale to a power of 2 so it can be mapped to a texture
@@ -655,7 +628,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage()
}
else
{
- LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+ LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
}
}
// Scale to a power of 2 so it can be mapped to a texture
@@ -675,7 +648,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
if (previewp->getWidth() == 0 || previewp->getHeight() == 0)
{
- LL_WARNS() << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << LL_ENDL;
+ LL_WARNS("Snapshot") << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << LL_ENDL;
return FALSE;
}
@@ -706,7 +679,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
previewp->mCameraRot = new_camera_rot;
// request a new snapshot whenever the camera moves, with a time delay
BOOL new_snapshot = gSavedSettings.getBOOL("AutoSnapshot") || previewp->mForceUpdateSnapshot;
- LL_DEBUGS() << "camera moved, updating thumbnail" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "camera moved, updating thumbnail" << LL_ENDL;
previewp->updateSnapshot(
new_snapshot, // whether a new snapshot is needed or merely invalidate the existing one
FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
@@ -722,7 +695,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
// time to produce a snapshot
if(!previewp->getSnapshotUpToDate())
{
- LL_DEBUGS() << "producing snapshot" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "producing snapshot" << LL_ENDL;
if (!previewp->mPreviewImage)
{
previewp->mPreviewImage = new LLImageRaw;
@@ -744,6 +717,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
previewp->getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE,
previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
FALSE,
previewp->mSnapshotBufferType,
previewp->getMaxImageSize()))
@@ -771,7 +745,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
previewp->getWindow()->decBusyCount();
previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode
previewp->mSnapshotActive = FALSE;
- LL_DEBUGS() << "done creating snapshot" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "done creating snapshot" << LL_ENDL;
}
if (!previewp->getThumbnailUpToDate())
@@ -862,7 +836,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
{
// We don't store the intermediate formatted image in mFormattedImage in the J2C case
- LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "Encoding new image of format J2C" << LL_ENDL;
LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
// Copy the preview
LLPointer<LLImageRaw> scaled = new LLImageRaw(
@@ -947,13 +921,13 @@ LLPointer<LLImageFormatted> LLSnapshotLivePreview::getFormattedImage()
}
else
{
- LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+ LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
}
}
// Create the new formatted image of the appropriate format.
LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
- LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "Encoding new image of format " << format << LL_ENDL;
switch (format)
{
@@ -978,7 +952,7 @@ LLPointer<LLImageFormatted> LLSnapshotLivePreview::getFormattedImage()
void LLSnapshotLivePreview::setSize(S32 w, S32 h)
{
- LL_DEBUGS() << "setSize(" << w << ", " << h << ")" << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "setSize(" << w << ", " << h << ")" << LL_ENDL;
setWidth(w);
setHeight(h);
}
@@ -1000,7 +974,7 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
{
- LL_DEBUGS() << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
// gen a new uuid for this asset
LLTransactionID tid;
tid.generate();
@@ -1023,12 +997,12 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
}
else
{
- LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+ LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
}
}
scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
- LL_DEBUGS() << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << LL_ENDL;
+ LL_DEBUGS("Snapshot") << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << LL_ENDL;
if (formatted->encode(scaled, 0.0f))
{
@@ -1037,7 +1011,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
std::string who_took_it;
LLAgentUI::buildFullname(who_took_it);
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;
std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;
LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY;
@@ -1056,7 +1030,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
else
{
LLNotificationsUtil::add("ErrorEncodingSnapshot");
- LL_WARNS() << "Error encoding snapshot" << LL_ENDL;
+ LL_WARNS("Snapshot") << "Error encoding snapshot" << LL_ENDL;
}
add(LLStatViewer::SNAPSHOT, 1);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 1dc1e65fe5..efa4a7fd66 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -55,8 +55,6 @@
#include "llviewershadermgr.h"
#include "llcontrolavatar.h"
-//#pragma optimize("", off)
-
static LLTrace::BlockTimerStatHandle FTM_FRUSTUM_CULL("Frustum Culling");
static LLTrace::BlockTimerStatHandle FTM_CULL_REBOUND("Cull Rebound Partition");
@@ -558,7 +556,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
if (!getSpatialPartition()->mRenderByGroup &&
getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&
getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
- getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_AVATAR &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)
{
setState(GEOM_DIRTY);
gPipeline.markRebuild(this, TRUE);
@@ -996,7 +996,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
}
LLSpatialGroup* group = drawablep->getSpatialGroup();
- llassert(group != NULL);
+ //llassert(group != NULL);
if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
{
@@ -1091,6 +1091,11 @@ public:
virtual bool earlyFail(LLViewerOctreeGroup* base_group)
{
+ if (LLPipeline::sReflectionRender)
+ {
+ return false;
+ }
+
LLSpatialGroup* group = (LLSpatialGroup*)base_group;
group->checkOcclusion();
@@ -2248,52 +2253,91 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
}
}
-void renderNormals(LLDrawable* drawablep)
-{
- LLVertexBuffer::unbind();
-
- LLVOVolume* vol = drawablep->getVOVolume();
- if (vol)
- {
- LLVolume* volume = vol->getVolume();
- gGL.pushMatrix();
- gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale"));
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
-
- for (S32 j = 0; j < face.mNumVertices; ++j)
- {
- gGL.begin(LLRender::LINES);
- LLVector4a n,p;
-
- n.setMul(face.mNormals[j], scale);
- p.setAdd(face.mPositions[j], n);
-
- gGL.diffuseColor4f(1,1,1,1);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
-
- if (face.mTangents)
- {
- n.setMul(face.mTangents[j], scale);
- p.setAdd(face.mPositions[j], n);
-
- gGL.diffuseColor4f(0,1,1,1);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
- }
- }
-
- gGL.popMatrix();
- }
+void renderNormals(LLDrawable *drawablep)
+{
+ if (!drawablep->isVisible())
+ return;
+
+ LLVertexBuffer::unbind();
+
+ LLVOVolume *vol = drawablep->getVOVolume();
+
+ if (vol)
+ {
+ LLVolume *volume = vol->getVolume();
+
+ // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
+ //
+ // SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't
+ // work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose
+ // transform. We get that effect here by pre-applying the inverse scale (twice, because
+ // one forward scale will be re-applied via the MVP in the vertex shader)
+
+ LLVector3 scale_v3 = vol->getScale();
+ float scale_len = scale_v3.length();
+ LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
+ obj_scale.normalize3();
+
+ // Normals &tangent line segments get scaled along with the object. Divide by scale length
+ // to keep the as-viewed lengths (relatively) constant with the debug setting length
+ float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+
+ // Create inverse-scale vector for normals
+ LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
+ inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
+ inv_scale.normalize3fast();
+
+ gGL.pushMatrix();
+ gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace &face = volume->getVolumeFace(i);
+
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a n, p;
+
+ n.setMul(face.mNormals[j], 1.0);
+ n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
+ n.normalize3fast();
+ n.mul(draw_length);
+ p.setAdd(face.mPositions[j], n);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+
+ // Tangents are simple vectors and do not require reorientation via pre-scaling
+ if (face.mTangents)
+ {
+ gGL.flush();
+ gGL.diffuseColor4f(0, 1, 1, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a t, p;
+
+ t.setMul(face.mTangents[j], 1.0f);
+ t.normalize3fast();
+ t.mul(draw_length);
+ p.setAdd(face.mPositions[j], t);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+ }
+ }
+
+ gGL.popMatrix();
+ }
}
S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale)
@@ -3120,13 +3164,13 @@ void renderRaycast(LLDrawable* drawablep)
LLGLEnable blend(GL_BLEND);
gGL.diffuseColor4f(0,1,1,0.5f);
- if (drawablep->getVOVolume())
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj && !vobj->isDead())
{
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- LLVOVolume* vobj = drawablep->getVOVolume();
LLVolume* volume = vobj->getVolume();
bool transform = true;
@@ -3355,7 +3399,7 @@ public:
for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
+ if(!drawable || drawable->isDead())
{
continue;
}
@@ -3445,7 +3489,7 @@ public:
U8 index = facep->getTextureIndex();
if (facep->mDrawInfo)
{
- if (index < 255)
+ if (index < FACE_DO_NOT_BATCH_TEXTURES)
{
if (facep->mDrawInfo->mTextureList.size() <= index)
{
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 7e65da42f7..919f386d29 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -685,6 +685,18 @@ public:
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
};
+class LLAvatarBridge : public LLVolumeBridge
+{
+public:
+ LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
+class LLControlAVBridge : public LLVolumeBridge
+{
+public:
+ LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
class LLHUDBridge : public LLVolumeBridge
{
public:
@@ -702,6 +714,18 @@ public:
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
};
+class LLAvatarPartition : public LLBridgePartition
+{
+public:
+ LLAvatarPartition(LLViewerRegion* regionp);
+};
+
+class LLControlAVPartition : public LLBridgePartition
+{
+public:
+ LLControlAVPartition(LLViewerRegion* regionp);
+};
+
class LLHUDPartition : public LLBridgePartition
{
public:
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index aba6599918..c5d5be3509 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -39,8 +39,8 @@
#include "llviewermedia_streamingaudio.h"
#include "llaudioengine.h"
-#ifdef LL_FMODEX
-# include "llaudioengine_fmodex.h"
+#ifdef LL_FMODSTUDIO
+# include "llaudioengine_fmodstudio.h"
#endif
#ifdef LL_OPENAL
@@ -71,6 +71,7 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpersistentnotificationstorage.h"
+#include "llpresetsmanager.h"
#include "llteleporthistory.h"
#include "llregionhandle.h"
#include "llsd.h"
@@ -88,6 +89,7 @@
#include "v3math.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llagentpicksinfo.h"
#include "llagentwearables.h"
@@ -106,7 +108,6 @@
//#include "llfirstuse.h"
#include "llfloaterhud.h"
#include "llfloaterland.h"
-#include "llfloaterpreference.h"
#include "llfloatertopobjects.h"
#include "llfloaterworldmap.h"
#include "llgesturemgr.h"
@@ -127,10 +128,12 @@
#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
+#include "llparcel.h"
#include "llpreview.h"
#include "llpreviewscript.h"
#include "llproxy.h"
#include "llproductinforequest.h"
+#include "llqueryflags.h"
#include "llselectmgr.h"
#include "llsky.h"
#include "llstatview.h"
@@ -141,6 +144,7 @@
#include "lltoolmgr.h"
#include "lltrans.h"
#include "llui.h"
+#include "lluiusage.h"
#include "llurldispatcher.h"
#include "llurlentry.h"
#include "llslurl.h"
@@ -158,6 +162,7 @@
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -174,6 +179,7 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llfasttimerview.h"
+#include "lltelemetry.h"
#include "llfloatermap.h"
#include "llweb.h"
#include "llvoiceclient.h"
@@ -181,8 +187,6 @@
#include "llnamebox.h"
#include "llnameeditor.h"
#include "llpostprocess.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llagentlanguage.h"
#include "llwearable.h"
#include "llinventorybridge.h"
@@ -198,6 +202,8 @@
#include "llexperiencelog.h"
#include "llcleanup.h"
+#include "llenvironment.h"
+
#include "llstacktrace.h"
#if LL_WINDOWS
@@ -208,7 +214,6 @@
// exported globals
//
bool gAgentMovementCompleted = false;
-S32 gMaxAgentGroups;
const std::string SCREEN_HOME_FILENAME = "screen_home%s.png";
const std::string SCREEN_LAST_FILENAME = "screen_last%s.png";
@@ -227,7 +232,6 @@ extern S32 gStartImageHeight;
static bool gGotUseCircuitCodeAck = false;
static std::string sInitialOutfit;
static std::string sInitialOutfitGender; // "male" or "female"
-static boost::signals2::connection sWearablesLoadedCon;
static bool gUseCircuitCallbackCalled = false;
@@ -236,7 +240,8 @@ LLSLURL LLStartUp::sStartSLURL;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
-static BOOL gRememberPassword = TRUE;
+static bool gRememberPassword = true;
+static bool gRememberUser = true;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@@ -244,9 +249,8 @@ static std::string gFirstSimSeedCap;
static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
static std::string gAgentStartLocation = "safe";
static bool mLoginStatePastUI = false;
+static bool mBenefitsSuccessfullyInit = false;
-const S32 DEFAULT_MAX_AGENT_GROUPS = 42;
-const S32 ALLOWED_MAX_AGENT_GROUPS = 500;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
@@ -277,6 +281,7 @@ void general_cert_done(const LLSD& notification, const LLSD& response);
void trust_cert_done(const LLSD& notification, const LLSD& response);
void apply_udp_blacklist(const std::string& csv);
bool process_login_success_response();
+void on_benefits_failed_callback(const LLSD& notification, const LLSD& response);
void transition_back_to_login_panel(const std::string& emsg);
void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group)
@@ -334,7 +339,6 @@ bool idle_startup()
static std::string auth_desc;
static std::string auth_message;
- static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server
// last location by default
@@ -350,13 +354,6 @@ bool idle_startup()
gIdleCallbacks.callFunctions();
gViewerWindow->updateUI();
- // There is a crash on updateClass, this is an attempt to get more information
- if (LLMortician::graveyardCount())
- {
- std::stringstream log_stream;
- LLMortician::logClass(log_stream);
- LL_INFOS() << log_stream.str() << LL_ENDL;
- }
LLMortician::updateClass();
const std::string delims (" ");
@@ -517,9 +514,9 @@ bool idle_startup()
if(!start_messaging_system(
message_template_path,
port,
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
FALSE,
std::string(),
responder,
@@ -533,6 +530,8 @@ bool idle_startup()
}
#if LL_WINDOWS
+ LLPROFILE_STARTUP();
+
// On the windows dev builds, unpackaged, the message.xml file will
// be located in indra/build-vc**/newview/<config>/app_settings.
std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
@@ -628,13 +627,13 @@ bool idle_startup()
delete gAudiop;
gAudiop = NULL;
-#ifdef LL_FMODEX
+#ifdef LL_FMODSTUDIO
#if !LL_WINDOWS
- if (NULL == getenv("LL_BAD_FMODEX_DRIVER"))
+ if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER"))
#endif // !LL_WINDOWS
- {
- gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable"));
- }
+ {
+ gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODExProfilerEnable"));
+ }
#endif
#ifdef LL_OPENAL
@@ -655,7 +654,7 @@ bool idle_startup()
#else
void* window_handle = NULL;
#endif
- bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
+ bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
if(init)
{
gAudiop->setMuted(TRUE);
@@ -701,19 +700,23 @@ bool idle_startup()
else if (gSavedSettings.getBOOL("AutoLogin"))
{
// Log into last account
- gRememberPassword = TRUE;
- gSavedSettings.setBOOL("RememberPassword", TRUE);
+ gRememberPassword = true;
+ gRememberUser = true;
+ gSavedSettings.setBOOL("RememberPassword", TRUE);
+ gSavedSettings.setBOOL("RememberUser", TRUE);
show_connect_box = false;
}
else if (gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
// Console provided login&password
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
+ gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = false;
}
else
{
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
+ gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = TRUE;
}
@@ -781,10 +784,7 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
- if (gUserCredential.notNull() && !LLPanelLogin::isCredentialSet())
- {
- LLPanelLogin::setFields( gUserCredential, gRememberPassword);
- }
+ LLPanelLogin::populateFields( gUserCredential, gRememberUser, gRememberPassword);
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@@ -816,6 +816,7 @@ bool idle_startup()
show_debug_menus();
// Hide the splash screen
+ LL_DEBUGS("AppInit") << "Hide the splash screen and show window" << LL_ENDL;
LLSplashScreen::hide();
// Push our window frontmost
gViewerWindow->getWindow()->show();
@@ -823,9 +824,12 @@ bool idle_startup()
// DEV-16927. The following code removes errant keystrokes that happen while the window is being
// first made visible.
#ifdef _WIN32
+ LL_DEBUGS("AppInit") << "Processing PeekMessage" << LL_ENDL;
MSG msg;
while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
- { }
+ {
+ }
+ LL_DEBUGS("AppInit") << "PeekMessage processed" << LL_ENDL;
#endif
display_startup();
timeout.reset();
@@ -873,7 +877,7 @@ bool idle_startup()
{
// TODO if not use viewer auth
// Load all the name information out of the login view
- LLPanelLogin::getFields(gUserCredential, gRememberPassword);
+ LLPanelLogin::getFields(gUserCredential, gRememberUser, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
@@ -885,14 +889,21 @@ bool idle_startup()
// STATE_LOGIN_SHOW state if we've gone backwards
mLoginStatePastUI = true;
- // save the credentials
- std::string userid = "unknown";
- if(gUserCredential.notNull())
- {
- userid = gUserCredential->userID();
- gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
- }
- gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
+ // save the credentials
+ std::string userid = "unknown";
+ if (gUserCredential.notNull())
+ {
+ userid = gUserCredential->userID();
+ if (gRememberUser)
+ {
+ gSecAPIHandler->addToCredentialMap("login_list", gUserCredential, gRememberPassword);
+ // Legacy viewers use this method to store user credentials, newer viewers
+ // reuse it to be compatible and to remember last session
+ gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
+ }
+ }
+ gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
+ gSavedSettings.setBOOL("RememberUser", gRememberUser);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
@@ -911,9 +922,9 @@ bool idle_startup()
}
// Set PerAccountSettingsFile to the default value.
- gSavedSettings.setString("PerAccountSettingsFile",
- gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
- LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")));
+ std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
+ gSavedSettings.setString("PerAccountSettingsFile", settings_per_account);
+ gDebugInfo["PerAccountSettingsFilename"] = settings_per_account;
// Note: can't store warnings files per account because some come up before login
@@ -951,21 +962,6 @@ bool idle_startup()
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
-
- //good a place as any to create user windlight directories
- std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", ""));
- LLFile::mkdir(user_windlight_path_name.c_str());
-
- std::string user_windlight_skies_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
- LLFile::mkdir(user_windlight_skies_path_name.c_str());
-
- std::string user_windlight_water_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
- LLFile::mkdir(user_windlight_water_path_name.c_str());
-
- std::string user_windlight_days_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", ""));
- LLFile::mkdir(user_windlight_days_path_name.c_str());
-
-
if (show_connect_box)
{
LLSLURL slurl;
@@ -1006,9 +1002,8 @@ bool idle_startup()
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
- init_start_screen(agent_location_id);
-
// Display the startup progress bar.
+ gViewerWindow->initTextures(agent_location_id);
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit"));
@@ -1115,6 +1110,8 @@ bool idle_startup()
// Its either downloading or declined.
// If optional was skipped this case shouldn't
// be reached.
+
+ LL_INFOS("LLStartup") << "Forcing a quit due to update." << LL_ENDL;
LLLoginInstance::getInstance()->disconnect();
LLAppViewer::instance()->forceQuit();
}
@@ -1135,7 +1132,24 @@ bool idle_startup()
{
// This was a certificate error, so grab the certificate
// and throw up the appropriate dialog.
- LLPointer<LLCertificate> certificate = gSecAPIHandler->getCertificate(response["certificate"]);
+ LLPointer<LLCertificate> certificate;
+ try
+ {
+ certificate = gSecAPIHandler->getCertificate(response["certificate"]);
+ }
+ catch (LLCertException &cert_exception)
+ {
+ LL_WARNS("LLStartup", "SECAPI") << "Caught " << cert_exception.what() << " certificate expception on getCertificate("<< response["certificate"] << ")" << LL_ENDL;
+ LLSD args;
+ args["REASON"] = LLTrans::getString(cert_exception.what());
+
+ LLNotificationsUtil::add("GeneralCertificateErrorShort", args, response,
+ general_cert_done);
+
+ reset_login();
+ gSavedSettings.setBOOL("AutoLogin", FALSE);
+ show_connect_box = true;
+ }
if(certificate)
{
LLSD args = transform_cert_args(certificate);
@@ -1221,7 +1235,6 @@ bool idle_startup()
display_startup();
gAgentCamera.init();
display_startup();
- set_underclothes_menu_options();
display_startup();
// Since we connected, save off the settings so the user doesn't have to
@@ -1417,12 +1430,19 @@ bool idle_startup()
// update the voice settings *after* gCacheName initialization
// so that we can construct voice UI that relies on the name cache
- LLVoiceClient::getInstance()->updateSettings();
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->updateSettings();
+ }
display_startup();
// create a container's instance for start a controlling conversation windows
// by the voice's events
LLFloaterIMContainer::getInstance();
+ if (gSavedSettings.getS32("ParcelMediaAutoPlayEnable") == 2)
+ {
+ LLViewerParcelAskPlay::getInstance()->loadSettings();
+ }
// *Note: this is where gWorldMap used to be initialized.
@@ -1478,8 +1498,7 @@ bool idle_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLEnvManagerNew::getInstance()->usePrefs(); // Load all presets and settings
- gSky.init(initial_sun_direction);
+ gSky.init();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -1544,12 +1563,14 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_AGENT_SEND );
}
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- display_startup();
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
+ {
+ display_startup();
+ }
+ lmc.processAcks();
}
- msg->processAcks();
display_startup();
return FALSE;
}
@@ -1574,8 +1595,6 @@ bool idle_startup()
send_complete_agent_movement(regionp->getHost());
gAssetStorage->setUpstream(regionp->getHost());
gCacheName->setUpstream(regionp->getHost());
- msg->newMessageFast(_PREHASH_EconomyDataRequest);
- gAgent.sendReliableMessage();
}
display_startup();
@@ -1601,25 +1620,27 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_AGENT_WAIT == LLStartUp::getStartupState())
{
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- if (gAgentMovementCompleted)
- {
- // Sometimes we have more than one message in the
- // queue. break out of this loop and continue
- // processing. If we don't, then this could skip one
- // or more login steps.
- break;
- }
- else
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
{
- LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
- << msg->getMessageName() << LL_ENDL;
+ if (gAgentMovementCompleted)
+ {
+ // Sometimes we have more than one message in the
+ // queue. break out of this loop and continue
+ // processing. If we don't, then this could skip one
+ // or more login steps.
+ break;
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
+ << gMessageSystem->getMessageName() << LL_ENDL;
+ }
+ display_startup();
}
- display_startup();
+ lmc.processAcks();
}
- msg->processAcks();
display_startup();
@@ -1651,8 +1672,20 @@ bool idle_startup()
if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
{
display_startup();
+
+ // request mute list
+ LL_INFOS() << "Requesting Mute List" << LL_ENDL;
+ LLMuteList::getInstance()->requestFromServer(gAgent.getID());
+
+ // Get L$ and ownership credit information
+ LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
+ LLStatusBar::sendMoneyBalanceRequest();
+
+ display_startup();
+
// Inform simulator of our language preference
LLAgentLanguage::update();
+
display_startup();
// unpack thin inventory
LLSD response = LLLoginInstance::getInstance()->getResponse();
@@ -1819,14 +1852,6 @@ bool idle_startup()
LLLandmark::registerCallbacks(msg);
display_startup();
- // request mute list
- LL_INFOS() << "Requesting Mute List" << LL_ENDL;
- LLMuteList::getInstance()->requestFromServer(gAgent.getID());
- display_startup();
- // Get L$ and ownership credit information
- LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
- LLStatusBar::sendMoneyBalanceRequest();
- display_startup();
// request all group information
LL_INFOS() << "Requesting Agent Data" << LL_ENDL;
gAgent.sendAgentDataUpdateRequest();
@@ -1883,14 +1908,13 @@ bool idle_startup()
// Set the show start location to true, now that the user has logged
// on with this install.
gSavedSettings.setBOOL("ShowStartLocation", TRUE);
-
- // Open Conversation floater on first login.
- LLFloaterReg::toggleInstanceOrBringToFront("im_container");
-
}
display_startup();
-
+
+ // Load stored local environment if needed.
+ LLEnvironment::instance().loadFromSettings();
+
// *TODO : Uncomment that line once the whole grid migrated to SLM and suppress it from LLAgent::handleTeleportFinished() (llagent.cpp)
//check_merchant_status();
@@ -1974,6 +1998,8 @@ bool idle_startup()
// JC - 7/20/2002
gViewerWindow->sendShapeToSim();
+ LLPresetsManager::getInstance()->createMissingDefault(PRESETS_CAMERA);
+
// The reason we show the alert is because we want to
// reduce confusion for when you log in and your provided
// location is not your expected location. So, if this is
@@ -2161,6 +2187,11 @@ bool idle_startup()
set_startup_status(1.0, "", "");
display_startup();
+ if (!mBenefitsSuccessfullyInit)
+ {
+ LLNotificationsUtil::add("FailedToGetBenefits", LLSD(), LLSD(), boost::bind(on_benefits_failed_callback, _1, _2));
+ }
+
// Let the map know about the inventory.
LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance();
if(floater_world_map)
@@ -2234,6 +2265,16 @@ bool idle_startup()
gAgentAvatarp->sendHoverHeight();
+ // look for parcels we own
+ send_places_query(LLUUID::null,
+ LLUUID::null,
+ "",
+ DFQ_AGENT_OWNED,
+ LLParcel::C_ANY,
+ "");
+
+ LLUIUsage::instance().clear();
+
return TRUE;
}
@@ -2299,8 +2340,8 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
- if (!release_notes_shown && (LLVersionInfo::getChannelAndVersion() != gLastRunVersion)
- && LLVersionInfo::getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
+ 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")
&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
@@ -2560,7 +2601,8 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("InitiateDownload", process_initiate_download);
msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply);
- msg->setHandlerFunc("GenericMessage", process_generic_message);
+ msg->setHandlerFunc("GenericMessage", process_generic_message);
+ msg->setHandlerFunc("LargeGenericMessage", process_large_generic_message);
msg->setHandlerFuncFast(_PREHASH_FeatureDisabled, process_feature_disabled_message);
}
@@ -2668,11 +2710,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
}
else
{
- // FIXME SH-3860 - this creates a race condition, where COF
- // changes (base outfit link added) after appearance update
- // request has been submitted.
- sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
-
bool do_copy = true;
bool do_append = false;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
@@ -2686,101 +2723,18 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
gAgentWearables.sendDummyAgentWearablesUpdate();
}
-//static
-void LLStartUp::saveInitialOutfit()
-{
- if (sInitialOutfit.empty()) {
- LL_DEBUGS() << "sInitialOutfit is empty" << LL_ENDL;
- return;
- }
-
- if (sWearablesLoadedCon.connected())
- {
- LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << LL_ENDL;
- sWearablesLoadedCon.disconnect();
- }
- LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << LL_ENDL;
- LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
-}
-
std::string& LLStartUp::getInitialOutfitName()
{
return sInitialOutfit;
}
-// Loads a bitmap to display during load
-void init_start_screen(S32 location_id)
+std::string LLStartUp::getUserId()
{
- if (gStartTexture.notNull())
- {
- gStartTexture = NULL;
- LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL;
- }
-
- LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL;
-
- U8 image_codec = IMG_CODEC_PNG;
- std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter();
-
- if ((S32)START_LOCATION_ID_LAST == location_id)
- {
- temp_str += LLStartUp::getScreenLastFilename();
- }
- else
- {
- std::string path = temp_str + LLStartUp::getScreenHomeFilename();
-
- if (!gDirUtilp->fileExists(path) && LLGridManager::getInstance()->isInProductionGrid())
- {
- // Fallback to old file, can be removed later
- // Home image only sets when user changes home, so it will take time for users to switch to pngs
- temp_str += "screen_home.bmp";
- image_codec = IMG_CODEC_BMP;
- }
- else
- {
- temp_str = path;
- }
- }
-
- LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
-
- // Turn off start screen to get around the occasional readback
- // driver bug
- if(!gSavedSettings.getBOOL("UseStartScreen"))
- {
- LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL;
- return;
- }
- else if(!start_image_frmted->load(temp_str) )
- {
- LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL;
- gStartTexture = NULL;
- }
- else
- {
- gStartImageWidth = start_image_frmted->getWidth();
- gStartImageHeight = start_image_frmted->getHeight();
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
- if (!start_image_frmted->decode(raw, 0.0f))
- {
- LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL;
- gStartTexture = NULL;
- }
- else
- {
- raw->expandToPowerOfTwo();
- gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ;
- }
- }
-
- if(gStartTexture.isNull())
- {
- gStartTexture = LLViewerTexture::sBlackImagep ;
- gStartImageWidth = gStartTexture->getWidth() ;
- gStartImageHeight = gStartTexture->getHeight() ;
- }
+ if (gUserCredential.isNull())
+ {
+ return "";
+ }
+ return gUserCredential->userID();
}
@@ -3268,10 +3222,70 @@ void apply_udp_blacklist(const std::string& csv)
}
+void on_benefits_failed_callback(const LLSD& notification, const LLSD& response)
+{
+ LL_WARNS("Benefits") << "Failed to load benefits information" << LL_ENDL;
+}
+
+bool init_benefits(LLSD& response)
+{
+ bool succ = true;
+
+ std::string package_name = response["account_type"].asString();
+ const LLSD& benefits_sd = response["account_level_benefits"];
+ if (!LLAgentBenefitsMgr::init(package_name, benefits_sd) ||
+ !LLAgentBenefitsMgr::initCurrent(package_name, benefits_sd))
+ {
+ succ = false;
+ }
+ else
+ {
+ LL_DEBUGS("Benefits") << "Initialized current benefits, level " << package_name << " from " << benefits_sd << LL_ENDL;
+ }
+ const LLSD& packages_sd = response["premium_packages"];
+ for(LLSD::map_const_iterator package_iter = packages_sd.beginMap();
+ package_iter != packages_sd.endMap();
+ ++package_iter)
+ {
+ std::string package_name = package_iter->first;
+ const LLSD& benefits_sd = package_iter->second["benefits"];
+ if (LLAgentBenefitsMgr::init(package_name, benefits_sd))
+ {
+ LL_DEBUGS("Benefits") << "Initialized benefits for package " << package_name << " from " << benefits_sd << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Benefits") << "Failed init for package " << package_name << " from " << benefits_sd << LL_ENDL;
+ succ = false;
+ }
+ }
+
+ if (!LLAgentBenefitsMgr::has("Base"))
+ {
+ LL_WARNS("Benefits") << "Benefits info did not include required package Base" << LL_ENDL;
+ succ = false;
+ }
+ if (!LLAgentBenefitsMgr::has("Premium"))
+ {
+ LL_WARNS("Benefits") << "Benefits info did not include required package Premium" << LL_ENDL;
+ succ = false;
+ }
+
+ // FIXME PREMIUM - for testing if login does not yet provide Premium Plus. Should be removed thereafter.
+ //if (succ && !LLAgentBenefitsMgr::has("Premium Plus"))
+ //{
+ // LLAgentBenefitsMgr::init("Premium Plus", packages_sd["Premium"]["benefits"]);
+ // llassert(LLAgentBenefitsMgr::has("Premium Plus"));
+ //}
+ return succ;
+}
+
bool process_login_success_response()
{
LLSD response = LLLoginInstance::getInstance()->getResponse();
+ mBenefitsSuccessfullyInit = init_benefits(response);
+
std::string text(response["udp_blacklist"]);
if(!text.empty())
{
@@ -3519,11 +3533,6 @@ bool process_login_success_response()
}
// Request the map server url
- // Non-agni grids have a different default location.
- if (!LLGridManager::getInstance()->isInProductionGrid())
- {
- gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/");
- }
std::string map_server_url = response["map-server-url"];
if(!map_server_url.empty())
{
@@ -3571,26 +3580,6 @@ bool process_login_success_response()
}
}
- LLSD global_textures = response["global-textures"][0];
- if(global_textures.size())
- {
- // Extract sun and moon texture IDs. These are used
- // in the LLVOSky constructor, but I can't figure out
- // how to pass them in. JC
- LLUUID id = global_textures["sun_texture_id"];
- if(id.notNull())
- {
- gSunTextureID = id;
- }
-
- id = global_textures["moon_texture_id"];
- if(id.notNull())
- {
- gMoonTextureID = id;
- }
-
- }
-
// set the location of the Agent Appearance service, from which we can request
// avatar baked textures if they are supported by the current region
std::string agent_appearance_url = response["agent_appearance_service"];
@@ -3614,27 +3603,6 @@ bool process_login_success_response()
LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);
}
- gMaxAgentGroups = DEFAULT_MAX_AGENT_GROUPS;
- if(response.has("max-agent-groups"))
- {
- S32 agent_groups = atoi(std::string(response["max-agent-groups"]).c_str());
- if (agent_groups > 0 && agent_groups <= ALLOWED_MAX_AGENT_GROUPS)
- {
- gMaxAgentGroups = agent_groups;
- LL_INFOS("LLStartup") << "gMaxAgentGroups read from login.cgi: "
- << gMaxAgentGroups << LL_ENDL;
- }
- else
- {
- LL_INFOS("LLStartup") << "Invalid value received, using defaults for gMaxAgentGroups: "
- << gMaxAgentGroups << LL_ENDL;
- }
- }
- else {
- LL_INFOS("LLStartup") << "Missing max-agent-groups, using default value for gMaxAgentGroups: "
- << gMaxAgentGroups << LL_ENDL;
- }
-
bool success = false;
// JC: gesture loading done below, when we have an asset system
// in place. Don't delete/clear gUserCredentials until then.
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index db37207022..116aeb36a7 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -80,7 +80,6 @@ typedef enum {
// exported symbols
extern bool gAgentMovementCompleted;
-extern S32 gMaxAgentGroups;
extern LLPointer<LLViewerTexture> gStartTexture;
class LLStartUp
@@ -111,10 +110,8 @@ public:
static void loadInitialOutfit( const std::string& outfit_folder_name,
const std::string& gender_name );
- //save loaded initial outfit into My Outfits category
- static void saveInitialOutfit();
-
static std::string& getInitialOutfitName();
+ static std::string getUserId();
static bool dispatchURL();
// if we have a SLURL or sim string ("Ahern/123/45") that started
@@ -128,6 +125,7 @@ public:
static LLViewerStats::PhaseMap& getPhases() { return *sPhases; }
private:
+ friend class LLStartupListener;
static LLSLURL sStartSLURL;
static std::string startupStateToString(EStartupState state);
diff --git a/indra/newview/llstartuplistener.cpp b/indra/newview/llstartuplistener.cpp
index d9a21f908e..5770b595d0 100644
--- a/indra/newview/llstartuplistener.cpp
+++ b/indra/newview/llstartuplistener.cpp
@@ -35,7 +35,7 @@
// external library headers
// other Linden headers
#include "llstartup.h"
-
+#include "stringize.h"
LLStartupListener::LLStartupListener(/* LLStartUp* instance */):
LLEventAPI("LLStartUp", "Access e.g. LLStartup::postStartupState()") /* ,
@@ -43,9 +43,33 @@ LLStartupListener::LLStartupListener(/* LLStartUp* instance */):
{
add("postStartupState", "Refresh \"StartupState\" listeners with current startup state",
&LLStartupListener::postStartupState);
+ add("getStateTable", "Reply with array of EStartupState string names",
+ &LLStartupListener::getStateTable);
}
void LLStartupListener::postStartupState(const LLSD&) const
{
LLStartUp::postStartupState();
}
+
+void LLStartupListener::getStateTable(const LLSD& event) const
+{
+ Response response(LLSD(), event);
+
+ // This relies on our knowledge that STATE_STARTED is the very last
+ // EStartupState value. If that ever stops being true, we're going to lie
+ // without realizing it. I can think of no reliable way to test whether
+ // the enum has been extended *beyond* STATE_STARTED. We could, of course,
+ // test whether stuff has been inserted before it, by testing its
+ // numerical value against the constant value as of the last time we
+ // looked; but that's pointless, as values inserted before STATE_STARTED
+ // will continue to work fine. The bad case is if new symbols get added
+ // *after* it.
+ LLSD table;
+ // note <= comparison: we want to *include* STATE_STARTED.
+ for (LLSD::Integer istate{0}; istate <= LLSD::Integer(STATE_STARTED); ++istate)
+ {
+ table.append(LLStartUp::startupStateToString(EStartupState(istate)));
+ }
+ response["table"] = table;
+}
diff --git a/indra/newview/llstartuplistener.h b/indra/newview/llstartuplistener.h
index a35e11f6eb..0b4380a568 100644
--- a/indra/newview/llstartuplistener.h
+++ b/indra/newview/llstartuplistener.h
@@ -40,6 +40,7 @@ public:
private:
void postStartupState(const LLSD&) const;
+ void getStateTable(const LLSD&) const;
//LLStartup* mStartup;
};
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index b8c227334d..0a87b14e17 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -38,6 +38,7 @@
#include "llfloaterbuycurrency.h"
#include "llbuycurrencyhtml.h"
#include "llpanelnearbymedia.h"
+#include "llpanelpresetscamerapulldown.h"
#include "llpanelpresetspulldown.h"
#include "llpanelvolumepulldown.h"
#include "llfloaterregioninfo.h"
@@ -172,8 +173,11 @@ BOOL LLStatusBar::postBuild()
mBoxBalance = getChild<LLTextBox>("balance");
mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this );
- mIconPresets = getChild<LLIconCtrl>( "presets_icon" );
- mIconPresets->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
+ mIconPresetsCamera = getChild<LLIconCtrl>( "presets_icon_camera" );
+ mIconPresetsCamera->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresetsCamera, this));
+
+ mIconPresetsGraphic = getChild<LLIconCtrl>( "presets_icon_graphic" );
+ mIconPresetsGraphic->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresets, this));
mBtnVolume = getChild<LLButton>( "volume_btn" );
mBtnVolume->setClickedCallback( onClickVolume, this );
@@ -228,6 +232,11 @@ BOOL LLStatusBar::postBuild()
mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp);
addChild(mSGPacketLoss);
+ mPanelPresetsCameraPulldown = new LLPanelPresetsCameraPulldown();
+ addChild(mPanelPresetsCameraPulldown);
+ mPanelPresetsCameraPulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
+ mPanelPresetsCameraPulldown->setVisible(FALSE);
+
mPanelPresetsPulldown = new LLPanelPresetsPulldown();
addChild(mPanelPresetsPulldown);
mPanelPresetsPulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
@@ -344,7 +353,8 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
mSGPacketLoss->setVisible(visible);
mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("MenuSearch"));
setBackgroundVisible(visible);
- mIconPresets->setVisible(visible);
+ mIconPresetsCamera->setVisible(visible);
+ mIconPresetsGraphic->setVisible(visible);
}
void LLStatusBar::debitBalance(S32 debit)
@@ -406,7 +416,20 @@ void LLStatusBar::sendMoneyBalanceRequest()
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_MoneyData);
msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
- gAgent.sendReliableMessage();
+
+ if (gDisconnected)
+ {
+ LL_DEBUGS() << "Trying to send message when disconnected, skipping balance request!" << LL_ENDL;
+ return;
+ }
+ if (!gAgent.getRegion())
+ {
+ LL_DEBUGS() << "LLAgent::sendReliableMessage No region for agent yet, skipping balance request!" << LL_ENDL;
+ return;
+ }
+ // Double amount of retries due to this request initially happening during busy stage
+ // Ideally this should be turned into a capability
+ gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
}
@@ -485,10 +508,34 @@ void LLStatusBar::onClickBuyCurrency()
LLFirstUse::receiveLindens(false);
}
+void LLStatusBar::onMouseEnterPresetsCamera()
+{
+ LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
+ LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon_camera" );
+ LLRect icon_rect = icon->getRect();
+ LLRect pulldown_rect = mPanelPresetsCameraPulldown->getRect();
+ pulldown_rect.setLeftTopAndSize(icon_rect.mLeft -
+ (pulldown_rect.getWidth() - icon_rect.getWidth()),
+ icon_rect.mBottom,
+ pulldown_rect.getWidth(),
+ pulldown_rect.getHeight());
+
+ pulldown_rect.translate(popup_holder->getRect().getWidth() - pulldown_rect.mRight, 0);
+ mPanelPresetsCameraPulldown->setShape(pulldown_rect);
+
+ // show the master presets pull-down
+ LLUI::getInstance()->clearPopups();
+ LLUI::getInstance()->addPopup(mPanelPresetsCameraPulldown);
+ mPanelNearByMedia->setVisible(FALSE);
+ mPanelVolumePulldown->setVisible(FALSE);
+ mPanelPresetsPulldown->setVisible(FALSE);
+ mPanelPresetsCameraPulldown->setVisible(TRUE);
+}
+
void LLStatusBar::onMouseEnterPresets()
{
LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
- LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon" );
+ LLIconCtrl* icon = getChild<LLIconCtrl>( "presets_icon_graphic" );
LLRect icon_rect = icon->getRect();
LLRect pulldown_rect = mPanelPresetsPulldown->getRect();
pulldown_rect.setLeftTopAndSize(icon_rect.mLeft -
@@ -527,6 +574,7 @@ void LLStatusBar::onMouseEnterVolume()
// show the master volume pull-down
LLUI::getInstance()->clearPopups();
LLUI::getInstance()->addPopup(mPanelVolumePulldown);
+ mPanelPresetsCameraPulldown->setVisible(FALSE);
mPanelPresetsPulldown->setVisible(FALSE);
mPanelNearByMedia->setVisible(FALSE);
mPanelVolumePulldown->setVisible(TRUE);
@@ -551,6 +599,7 @@ void LLStatusBar::onMouseEnterNearbyMedia()
LLUI::getInstance()->clearPopups();
LLUI::getInstance()->addPopup(mPanelNearByMedia);
+ mPanelPresetsCameraPulldown->setVisible(FALSE);
mPanelPresetsPulldown->setVisible(FALSE);
mPanelVolumePulldown->setVisible(FALSE);
mPanelNearByMedia->setVisible(TRUE);
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index cad877f799..3002b91c10 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -41,6 +41,7 @@ class LLUICtrl;
class LLUUID;
class LLFrameTimer;
class LLStatGraph;
+class LLPanelPresetsCameraPulldown;
class LLPanelPresetsPulldown;
class LLPanelVolumePulldown;
class LLPanelNearByMedia;
@@ -99,6 +100,7 @@ private:
void onClickBuyCurrency();
void onVolumeChanged(const LLSD& newvalue);
+ void onMouseEnterPresetsCamera();
void onMouseEnterPresets();
void onMouseEnterVolume();
void onMouseEnterNearbyMedia();
@@ -123,7 +125,8 @@ private:
LLStatGraph *mSGBandwidth;
LLStatGraph *mSGPacketLoss;
- LLIconCtrl *mIconPresets;
+ LLIconCtrl *mIconPresetsCamera;
+ LLIconCtrl *mIconPresetsGraphic;
LLButton *mBtnVolume;
LLTextBox *mBoxBalance;
LLButton *mMediaToggle;
@@ -135,6 +138,7 @@ private:
S32 mSquareMetersCommitted;
LLFrameTimer* mBalanceTimer;
LLFrameTimer* mHealthTimer;
+ LLPanelPresetsCameraPulldown* mPanelPresetsCameraPulldown;
LLPanelPresetsPulldown* mPanelPresetsPulldown;
LLPanelVolumePulldown* mPanelVolumePulldown;
LLPanelNearByMedia* mPanelNearByMedia;
diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp
new file mode 100644
index 0000000000..0c63e2fede
--- /dev/null
+++ b/indra/newview/lltelemetry.cpp
@@ -0,0 +1,145 @@
+ /**
+ * @file lltelemetry.cpp
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltelemetry.h"
+
+#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+ #if LL_WINDOWS
+ #include "llwin32headers.h"
+
+ // build-vc120-64\packages\lib\release
+ // build-vc150-64\packages\lib\release
+ #ifdef _MSC_VER
+ #pragma comment(lib,"rad_tm_win64.lib")
+ #else
+ #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows"
+ #endif
+ #endif // LL_WINDOWS
+
+ #if LL_DARWIN
+ #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin"
+ #endif
+
+ #if LL_LINUX
+ #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux"
+ #endif
+
+//
+// local consts
+//
+static const tm_int32 TELEMETRY_BUFFER_SIZE = 8 * 1024 * 1024;
+
+//
+// local globals
+//
+static char *gTelemetryBufferPtr = NULL; // Telemetry
+
+static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] =
+{
+ "Telemetry pass: connected" // TM_OK
+ , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED
+ , "Telemetry FAIL: invalid paramater" // TMERR_INVALID_PARAM
+ , "Telemetry FAIL: DLL not found" // TMERR_NULL_API
+ , "Telemetry FAIL: out of resources" // TMERR_OUT_OF_RESOURCES
+ , "Telemetry FAIL: tmInitialize() not called" // TMERR_UNINITIALIZED
+ , "Telemetry FAIL: bad hostname" // TMERR_BAD_HOSTNAME
+ , "Telemetry FAIL: couldn't connect to server" // TMERR_COULD_NOT_CONNECT
+ , "Telemetry FAIL: unknown network error" // TMERR_UNKNOWN_NETWORK
+ , "Telemetry FAIL: tmShutdown() already called" // TMERR_ALREADY_SHUTDOWN
+ , "Telemetry FAIL: memory buffer too small" // TMERR_ARENA_TOO_SMALL
+ , "Telemetry FAIL: server handshake error" // TMERR_BAD_HANDSHAKE
+ , "Telemetry FAIL: unaligned parameters" // TMERR_UNALIGNED
+ , "Telemetry FAIL: network not initialized" // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen()
+ , "Telemetry FAIL: bad version" // TMERR_BAD_VERSION
+ , "Telemetry FAIL: timer too large" // TMERR_BAD_TIMER
+ , "Telemetry FAIL: tmOpen() already called" // TMERR_ALREADY_OPENED
+ , "Telemetry FAIL: tmInitialize() already called" // TMERR_ALREADY_INITIALIZED
+ , "Telemetry FAIL: could't open file" // TMERR_FILE_OPEN_FAILED
+ , "Telemetry FAIL: tmOpen() failed networking" // TMERR_INIT_NETWORKING_FAILED
+};
+
+//
+// exported functionality
+//
+
+void telemetry_shutdown()
+{
+ #if LL_WINDOWS
+ if (gTelemetryBufferPtr)
+ {
+ tmClose(0);
+ tmShutdown();
+
+ delete[] gTelemetryBufferPtr;
+ gTelemetryBufferPtr = NULL;
+ }
+ #endif
+}
+
+void telemetry_startup()
+{
+ #if LL_WINDOWS
+ tmLoadLibrary(TM_RELEASE); // Loads .dll
+
+ gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ];
+ tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr);
+
+ tm_error telemetry_status = tmOpen(
+ 0, // unused
+ "SecondLife", // app name
+ __DATE__ " " __TIME__, // build identifier
+ "localhost", // server name (or filename)
+ TMCT_TCP, // connection type (or TMCT_FILE)
+ 4719, // port
+ TMOF_INIT_NETWORKING, // open flags
+ 250 ); // timeout ms
+
+ if (telemetry_status == TMERR_UNKNOWN)
+ {
+ LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL;
+ }
+ else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED))
+ {
+ LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL;
+ free(gTelemetryBufferPtr);
+ gTelemetryBufferPtr = NULL;
+ }
+ #endif // LL_WINDOWS
+}
+
+// Called after we render a frame
+void telemetry_update()
+{
+ #if LL_WINDOWS
+ if (gTelemetryBufferPtr)
+ {
+ tmTick(0);
+ }
+ #endif
+}
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h
new file mode 100644
index 0000000000..a73e5fcfa2
--- /dev/null
+++ b/indra/newview/lltelemetry.h
@@ -0,0 +1,81 @@
+/**
+ * @file lltelemetry.h
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*
+To use:
+
+1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below
+
+2. Include this header file
+ #include "lltelemetry.h"
+
+3. Add zones to the functions you wish to profile
+ void onFoo()
+ {
+ LLPROFILE_ZONE("Foo");
+ }
+*/
+//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1
+
+// Default NO local telemetry profiling
+#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+ #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0
+ #define LLPROFILE_SHUTDOWN( ...) {}
+ #define LLPROFILE_STARTUP( ...) {}
+ #define LLPROFILE_UPDATE( ...) {}
+
+ #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b)
+ #define LLPROFILE_ENTER(name)
+ #define LLPROFILE_ENTER_FORMAT(format, ...)
+ #define LLPROFILE_FUNCTION
+ #define LLPROFILE_LEAVE()
+ #define LLPROFILE_THREAD_NAME(name)
+ #define LLPROFILE_ZONE(name)
+ #define LLPROFILE_ZONE_FORMAT(format, ...)
+#else
+ #include <rad_tm.h>
+
+ #define LLPROFILE_SHUTDOWN telemetry_shutdown
+ #define LLPROFILE_STARTUP telemetry_startup
+ #define LLPROFILE_UPDATE telemetry_update
+
+ #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b)
+ #define LLPROFILE_ENTER(name) tmEnter(0, 0, name)
+ #define LLPROFILE_ENTER_FORMAT(format, ...) tmEnter(0, 0, format, __VA_ARGS__)
+ #define LLPROFILE_FUNCTION tmFunction(0, 0)
+ #define LLPROFILE_LEAVE() tmLeave(0)
+ #define LLPROFILE_THREAD_NAME(name) tmThreadName(0, 0, name)
+ #define LLPROFILE_ZONE(name) tmZone(0, 0, name)
+ #define LLPROFILE_ZONE_FORMAT(format, ...) tmZone(0, 0, format, __VA_ARGS__)
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+
+//
+// exported functionality
+//
+
+extern void telemetry_startup();
+extern void telemetry_shutdown();
+extern void telemetry_update(); // called after every frame update
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index 8a5704939a..93fa457bd0 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -33,6 +33,8 @@
#include "lldir.h"
#include "llteleporthistory.h"
#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
// Max offset for two global positions to consider them as equal
const F64 MAX_GLOBAL_POS_OFFSET = 5.0f;
@@ -253,3 +255,23 @@ void LLTeleportHistoryStorage::goToItem(S32 idx)
gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
}
+void LLTeleportHistoryStorage::showItemOnMap(S32 idx)
+{
+ // Validate specified index.
+ if (idx < 0 || idx >= (S32)mItems.size())
+ {
+ LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL;
+ dump();
+ return;
+ }
+
+ LLVector3d landmark_global_pos = mItems[idx].mGlobalPos;
+
+ LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+ if (!landmark_global_pos.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(landmark_global_pos);
+ LLFloaterReg::showInstance("world_map", "center");
+ }
+}
+
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index 946ac0af1a..3578923fd7 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -107,6 +107,13 @@ public:
*/
void goToItem(S32 idx);
+ /**
+ * Show specific item on map.
+ *
+ * The item is specified by its index (starting from 0).
+ */
+ void showItemOnMap(S32 idx);
+
private:
void load();
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e2deb7ce1d..a9f19dc32d 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -52,7 +52,8 @@ const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;
const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
-const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
+const S32 TEXTURE_FAST_CACHE_DATA_SIZE = 16 * 16 * 4;
+const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = TEXTURE_FAST_CACHE_DATA_SIZE + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress.
class LLTextureCacheWorker : public LLWorkerClass
@@ -616,6 +617,9 @@ bool LLTextureCacheRemoteWorker::doWrite()
if(idx >= 0)
{
// write to the fast cache.
+ // mRawImage is not entirely safe here since it is a pointer to one owned by cache worker,
+ // it could have been retrieved via getRequestFinished() and then modified.
+ // If writeToFastCache crashes, something is wrong around fetch worker.
if(!mCache->writeToFastCache(mID, idx, mRawImage, mRawDiscardLevel))
{
LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
@@ -1822,29 +1826,28 @@ void LLTextureCache::purgeTextures(bool validate)
iter != time_idx_set.end(); ++iter)
{
S32 idx = iter->second;
- bool purge_entry = false;
- std::string filename = getTextureFileName(entries[idx].mID);
- if (cache_size >= purged_cache_size)
- {
- purge_entry = true;
- }
- else if (validate)
+ bool purge_entry = false;
+ if (validate)
{
// make sure file exists and is the correct size
U32 uuididx = entries[idx].mID.mData[0];
if (uuididx == validate_idx)
{
+ std::string filename = getTextureFileName(entries[idx].mID);
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
// mHeaderAPRFilePoolp because this is under header mutex in main thread
S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp);
if (bodysize != entries[idx].mBodySize)
{
- LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
- << filename << LL_ENDL;
+ LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize << filename << LL_ENDL;
purge_entry = true;
}
}
}
+ else if (cache_size >= purged_cache_size)
+ {
+ purge_entry = true;
+ }
else
{
break;
@@ -1853,6 +1856,7 @@ void LLTextureCache::purgeTextures(bool validate)
if (purge_entry)
{
purge_count++;
+ std::string filename = getTextureFileName(entries[idx].mID);
LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL;
cache_size -= entries[idx].mBodySize;
removeEntry(idx, entries[idx], filename) ;
@@ -2065,7 +2069,9 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
}
S32 image_size = head[0] * head[1] * head[2];
- if(!image_size) //invalid
+ if(image_size <= 0
+ || image_size > TEXTURE_FAST_CACHE_DATA_SIZE
+ || head[3] < 0) //invalid
{
closeFastCache();
return NULL;
@@ -2087,46 +2093,6 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
return raw;
}
-#if LL_WINDOWS
-
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
- if (code == STATUS_MSC_EXCEPTION)
- {
- // C++ exception, go on
- return EXCEPTION_CONTINUE_SEARCH;
- }
- else
- {
- // handle it
- return EXCEPTION_EXECUTE_HANDLER;
- }
-}
-
-//due to unwinding
-void dupe(LLPointer<LLImageRaw> &raw)
-{
- raw = raw->duplicate();
-}
-
-void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
-{
- __try
- {
- dupe(raw);
- }
- __except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
- {
- // convert to C++ styled exception
- char integer_string[32];
- sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
- throw std::exception(integer_string);
- }
-}
-#endif
-
//return the fast cache location
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
@@ -2143,8 +2109,9 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
c = raw->getComponents();
S32 i = 0 ;
-
- while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+
+ // Search for a discard level that will fit into fast cache
+ while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_DATA_SIZE)
{
++i ;
}
@@ -2155,31 +2122,8 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
h >>= i;
if(w * h *c > 0) //valid
{
- //make a duplicate to keep the original raw image untouched.
-
- try
- {
-#if LL_WINDOWS
- // Temporary diagnostics for scale/duplicate crash
- logExceptionDupplicate(raw);
-#else
- raw = raw->duplicate();
-#endif
- }
- catch (...)
- {
- removeFromCache(image_id);
- LL_ERRS() << "Failed to cache image: " << image_id
- << " local id: " << id
- << " Exception: " << boost::current_exception_diagnostic_information()
- << " Image new width: " << w
- << " Image new height: " << h
- << " Image new components: " << c
- << " Image discard difference: " << i
- << LL_ENDL;
-
- return false;
- }
+ // Make a duplicate to keep the original raw image untouched.
+ raw = raw->duplicate();
if (raw->isBufferInvalid())
{
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 6046f2b9df..e1c752b58e 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -45,6 +45,11 @@ class LLTextureCache : public LLWorkerThread
friend class LLTextureCacheLocalFileWorker;
private:
+
+#if LL_WINDOWS
+#pragma pack(push,1)
+#endif
+
// Entries
static const U32 sHeaderEncoderStringSize = 32;
struct EntriesInfo
@@ -73,7 +78,10 @@ private:
U32 mTime; // seconds since 1/1/1970
};
-
+#if LL_WINDOWS
+#pragma pack(pop)
+#endif
+
public:
class Responder : public LLResponder
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index e2bb904eff..1c4a56b549 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -73,9 +73,6 @@
#include "llavatarappearancedefines.h"
-static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-static const F32 CONTEXT_FADE_TIME = 0.08f;
static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
@@ -143,17 +140,17 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
{
- if ( mBakeTextureEnabled && mModeSelector->getSelectedIndex() != 2)
+ if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2)
{
- mModeSelector->setSelectedIndex(2, 0);
+ mModeSelector->selectByValue(2);
onModeSelect(0,this);
}
}
else
{
- if (mModeSelector->getSelectedIndex() == 2)
+ if (mModeSelector->getValue().asInteger() == 2)
{
- mModeSelector->setSelectedIndex(0, 0);
+ mModeSelector->selectByValue(0);
onModeSelect(0,this);
}
@@ -350,7 +347,7 @@ BOOL LLFloaterTexturePicker::postBuild()
}
mTentativeLabel = getChild<LLTextBox>("Multiple");
- mResolutionLabel = getChild<LLTextBox>("unknown");
+ mResolutionLabel = getChild<LLTextBox>("size_lbl");
childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
@@ -366,9 +363,9 @@ BOOL LLFloaterTexturePicker::postBuild()
mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
- mModeSelector = getChild<LLRadioGroup>("mode_selection");
+ mModeSelector = getChild<LLComboBox>("mode_selection");
mModeSelector->setCommitCallback(onModeSelect, this);
- mModeSelector->setSelectedIndex(0, 0);
+ mModeSelector->selectByValue(0);
if(mInventoryPanel)
{
@@ -398,7 +395,7 @@ BOOL LLFloaterTexturePicker::postBuild()
- if (!mImageAssetID.isNull())
+ if(!mImageAssetID.isNull())
{
mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
}
@@ -435,66 +432,15 @@ BOOL LLFloaterTexturePicker::postBuild()
getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);
getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this);
- setBakeTextureEnabled(FALSE);
+ setBakeTextureEnabled(TRUE);
return TRUE;
}
// virtual
void LLFloaterTexturePicker::draw()
{
- if (mOwner)
- {
- // draw cone of context pointing back to texture swatch
- LLRect owner_rect;
- mOwner->localRectToOtherView(mOwner->getLocalRect(), &owner_rect, this);
- LLRect local_rect = getLocalRect();
- if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
- gGL.begin(LLRender::QUADS);
- {
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
-
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mTop);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
-
-
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
- gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
- gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom);
- gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom);
- }
- gGL.end();
- }
- }
-
- if (gFocusMgr.childHasMouseCapture(getDragHandle()))
- {
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
- }
- else
- {
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
- }
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, mOwner);
updateImageStats();
@@ -810,27 +756,27 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- int mode = self->mModeSelector->getSelectedIndex();
+ int index = self->mModeSelector->getValue().asInteger();
- self->getChild<LLButton>("Default")->setVisible(mode == 0);
- self->getChild<LLButton>("Blank")->setVisible(mode == 0);
- self->getChild<LLButton>("None")->setVisible(mode == 0);
- self->getChild<LLButton>("Pipette")->setVisible(mode == 0);
- self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode == 0);
- self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode == 0);
+ self->getChild<LLButton>("Default")->setVisible(index == 0 ? TRUE : FALSE);
+ self->getChild<LLButton>("Blank")->setVisible(index == 0 ? TRUE : FALSE);
+ self->getChild<LLButton>("None")->setVisible(index == 0 ? TRUE : FALSE);
+ self->getChild<LLButton>("Pipette")->setVisible(index == 0 ? TRUE : FALSE);
+ 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(mode == 1);
- self->getChild<LLButton>("l_rem_btn")->setVisible(mode == 1);
- self->getChild<LLButton>("l_upl_btn")->setVisible(mode == 1);
- self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(mode == 1);
+ 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);
+ self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(index == 1 ? TRUE : FALSE);
- self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(mode == 2);
- self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(false);// mode == 2);
+ self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(index == 2 ? TRUE : FALSE);
+ self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE);
- if (mode == 2)
+ if (index == 2)
{
self->stopUsingPipette();
@@ -1137,7 +1083,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
{
- mModeSelector->setIndexEnabled(1,enabled);
+ mModeSelector->setEnabledByValue(1, enabled);
}
void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
@@ -1145,18 +1091,18 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
BOOL changed = (enabled != mBakeTextureEnabled);
mBakeTextureEnabled = enabled;
- mModeSelector->setIndexEnabled(2, enabled);
+ mModeSelector->setEnabledByValue(2, enabled);
- if (!mBakeTextureEnabled && (mModeSelector->getSelectedIndex() == 2))
+ if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2))
{
- mModeSelector->setSelectedIndex(0, 0);
+ mModeSelector->selectByValue(0);
}
if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
{
- if (mModeSelector->getSelectedIndex() != 2)
+ if (mModeSelector->getValue().asInteger() != 2)
{
- mModeSelector->setSelectedIndex(2, 0);
+ mModeSelector->selectByValue(2);
}
}
onModeSelect(0, this);
@@ -1211,8 +1157,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
- mFallbackImage(p.fallback_image),
- mBakeTextureEnabled(FALSE)
+ mFallbackImage(p.fallback_image)
{
// Default of defaults is white image for diff tex
@@ -1405,7 +1350,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
}
if (texture_floaterp)
{
- texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+ texture_floaterp->setBakeTextureEnabled(TRUE);
}
LLFloater* root_floater = gFloaterView->getParentFloater(this);
@@ -1584,7 +1529,6 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
{
- mBakeTextureEnabled = enabled;
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if (floaterp)
{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index b2a34a37c4..92f6f89af6 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -36,7 +36,6 @@
#include "llstring.h"
#include "lluictrl.h"
#include "llpermissionsflags.h"
-#include "llradiogroup.h"
#include "lltextbox.h" // for params
#include "llviewerinventory.h"
#include "llviewborder.h" // for params
@@ -44,7 +43,7 @@
#include "llviewertexture.h"
#include "llwindow.h"
-class LLButton;
+class LLComboBox;
class LLFloaterTexturePicker;
class LLInventoryItem;
class LLViewerFetchedTexture;
@@ -239,7 +238,6 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
- BOOL mBakeTextureEnabled;
};
//////////////////////////////////////////////////////////////////////////////////////////
@@ -367,7 +365,7 @@ protected:
LLSaveFolderState mSavedFolderState;
BOOL mSelectedItemPinned;
- LLRadioGroup* mModeSelector;
+ LLComboBox* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
private:
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index fe058024f6..f64db7beb5 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -1977,6 +1977,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
setState(WAIT_ON_WRITE);
++mCacheWriteCount;
CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
+ // This call might be under work mutex, but mRawImage is not nessesary safe here.
+ // If something retrieves it via getRequestFinished() and modifies, image won't
+ // be protected by work mutex and won't be safe to use here nor in cache worker.
+ // So make sure users of getRequestFinished() does not attempt to modify image while
+ // fetcher is working
mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
mFormattedImage->getData(), datasize,
mFileSize, mRawImage, mDecodedDiscard, responder);
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index cdf8868597..2aa194e141 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -92,6 +92,7 @@ public:
void deleteAllRequests();
// Threads: T*
+ // keep in mind that if fetcher isn't done, it still might need original raw image
bool getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,
LLCore::HttpStatus& last_http_get_status);
diff --git a/indra/newview/lltexturestats.cpp b/indra/newview/lltexturestats.cpp
index b55b4d9ca4..8f4b7d000c 100644
--- a/indra/newview/lltexturestats.cpp
+++ b/indra/newview/lltexturestats.cpp
@@ -46,8 +46,8 @@ void send_texture_stats_to_sim(const LLSD &texture_stats)
LLUUID agent_id = gAgent.getID();
texture_stats_report["agent_id"] = agent_id;
texture_stats_report["region_id"] = gAgent.getRegion()->getRegionID();
- texture_stats_report["viewer_channel"] = LLVersionInfo::getChannel();
- texture_stats_report["viewer_version"] = LLVersionInfo::getVersion();
+ texture_stats_report["viewer_channel"] = LLVersionInfo::instance().getChannel();
+ texture_stats_report["viewer_version"] = LLVersionInfo::instance().getVersion();
texture_stats_report["stats_data"] = texture_stats;
std::string texture_cap_url = gAgent.getRegion()->getCapability("TextureStats");
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 0d2edc0268..7a0f69fed5 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -423,8 +423,8 @@ void LLAvatarTexBar::draw()
LLColor4 color;
U32 line_num = 1;
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
@@ -549,7 +549,7 @@ void LLGLTexMemBar::draw()
U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
- text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+ text = llformat("GL Tot: %d/%d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
total_mem.value(),
max_total_mem.value(),
bound_mem.value(),
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 870e0d94f0..bf56a10d4d 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -612,11 +612,8 @@ S32 LLToast::notifyParent(const LLSD& info)
//static
void LLToast::updateClass()
{
- for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
- iter != LLInstanceTracker<LLToast>::endInstances(); )
+ for (auto& toast : LLInstanceTracker<LLToast>::instance_snapshot())
{
- LLToast& toast = *iter++;
-
toast.updateHoveredState();
}
}
@@ -624,22 +621,6 @@ void LLToast::updateClass()
// static
void LLToast::cleanupToasts()
{
- LLToast * toastp = NULL;
-
- while (LLInstanceTracker<LLToast>::instanceCount() > 0)
- {
- { // Need to scope iter to allow deletion
- LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
- toastp = &(*iter);
- }
-
- //LL_INFOS() << "Cleaning up toast id " << toastp->getNotificationID() << LL_ENDL;
-
- // LLToast destructor will remove it from the LLInstanceTracker.
- if (!toastp)
- break; // Don't get stuck in the loop if a null pointer somehow got on the list
-
- delete toastp;
- }
+ LLInstanceTracker<LLToast>::instance_snapshot().deleteAll();
}
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 941cb410fc..8baad30e8f 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -34,7 +34,6 @@
#include "llfontgl.h"
#include "lltextbox.h"
#include "llbutton.h"
-#include "llcheckboxctrl.h"
#include "llkeyboard.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
@@ -62,9 +61,8 @@ static const S32 HPAD = 25;
static const S32 BTN_HPAD = 8;
LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
- : LLToastPanel(notification),
+ : LLCheckBoxToastPanel(notification),
mDefaultOption( 0 ),
- mCheck(NULL),
mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
mLabel(notification->getName()),
mLineEditor(NULL)
@@ -123,6 +121,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
data.mURLExternal = mNotification->getURLOpenExternally();
}
+ if((*it).has("width"))
+ {
+ data.mWidth = (*it)["width"].asInteger();
+ }
+
mButtonData.push_back(data);
option_index++;
}
@@ -161,15 +164,29 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
// Calc total width of buttons
S32 button_width = 0;
S32 sp = font->getWidth(std::string("OO"));
+ S32 btn_total_width = 0;
+ S32 default_size_btns = 0;
for( S32 i = 0; i < num_options; i++ )
- {
+ {
S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD;
- button_width = llmax( w, button_width );
+ if (mButtonData[i].mWidth > w)
+ {
+ btn_total_width += mButtonData[i].mWidth;
+ }
+ else
+ {
+ button_width = llmax(w, button_width);
+ default_size_btns++;
+ }
}
- S32 btn_total_width = button_width;
+
if( num_options > 1 )
{
- btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD);
+ btn_total_width = btn_total_width + (button_width * default_size_btns) + ((num_options - 1) * BTN_HPAD);
+ }
+ else
+ {
+ btn_total_width = llmax(btn_total_width, button_width);
}
// Message: create text box using raw string, as text has been structure deliberately
@@ -194,6 +211,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
- 3*VPAD - BTN_HEIGHT;
// reshape to calculate real text width and height
msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height );
+
+ if ("GroupLimitInfo" == mNotification->getName() || "GroupLimitInfoPlus" == mNotification->getName())
+ {
+ msg_box->setSkipLinkUnderline(true);
+ }
msg_box->setValue(msg);
S32 pixel_width = msg_box->getTextPixelWidth();
@@ -268,14 +290,15 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setMaxTextChars(edit_text_max_chars);
mLineEditor->setText(edit_text_contents);
- if("SaveOutfitAs" == mNotification->getName())
+ std::string notif_name = mNotification->getName();
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
// decrease limit of line editor of teleport offer dialog to avoid truncation of
// location URL in invitation message, see EXT-6891
- if ("OfferTeleport" == mNotification->getName())
+ if ("OfferTeleport" == notif_name)
{
mLineEditor->setMaxTextLength(gSavedSettings.getS32(
"teleport_offer_invitation_max_length"));
@@ -329,7 +352,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
if(btn)
{
btn->setName(options[i].first);
- btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ));
+ btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, (mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth, BTN_HEIGHT ));
btn->setLabel(options[i].second);
btn->setFont(font);
@@ -344,23 +367,10 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
btn->setFocus(TRUE);
}
}
- button_left += button_width + BTN_HPAD;
+ button_left += ((mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth) + BTN_HPAD;
}
- std::string ignore_label;
-
- if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
- }
- if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label);
- }
- else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
- }
+ setCheckBoxes(HPAD, VPAD);
// *TODO: check necessity of this code
//gFloaterView->adjustToFitScreen(this, FALSE);
@@ -380,46 +390,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
LLTransientFloaterMgr::GLOBAL, this);
}
-bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
-{
- mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
-
- if(!mCheck)
- {
- return false;
- }
-
- const LLFontGL* font = mCheck->getFont();
- const S32 LINE_HEIGHT = font->getLineHeight();
-
- std::vector<std::string> lines;
- boost::split(lines, check_title, boost::is_any_of("\n"));
-
- // Extend dialog for "check next time"
- S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
- S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
- max_msg_width = llmax(max_msg_width, check_width);
- S32 dialog_width = max_msg_width + 2 * HPAD;
-
- S32 dialog_height = LLToastPanel::getRect().getHeight();
- dialog_height += LINE_HEIGHT * lines.size();
- dialog_height += LINE_HEIGHT / 2;
-
- LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
-
- S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
-
- // set check_box's attributes
- LLRect check_rect;
- mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT*lines.size()));
- mCheck->setLabel(check_title);
- mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
-
- LLToastPanel::addChild(mCheck);
-
- return true;
-}
-
void LLToastAlertPanel::setVisible( BOOL visible )
{
// only make the "ding" sound if it's newly visible
@@ -569,16 +539,3 @@ void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
mNotification->respond(response); // new notification reponse
}
-
-void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
-{
- // checkbox sometimes means "hide and do the default" and
- // other times means "warn me again". Yuck. JC
- BOOL check = ctrl->getValue().asBoolean();
- if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
- {
- // question was "show again" so invert value to get "ignore"
- check = !check;
- }
- mNotification->setIgnored(check);
-}
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
index 15bf11d42c..bd34e40642 100644
--- a/indra/newview/lltoastalertpanel.h
+++ b/indra/newview/lltoastalertpanel.h
@@ -46,7 +46,7 @@ class LLLineEditor;
*/
class LLToastAlertPanel
- : public LLToastPanel
+ : public LLCheckBoxToastPanel
{
LOG_CLASS(LLToastAlertPanel);
public:
@@ -61,13 +61,11 @@ public:
virtual void draw();
virtual void setVisible( BOOL visible );
- bool setCheckBox( const std::string&, const std::string& );
void setCaution(BOOL val = TRUE) { mCaution = val; }
// If mUnique==TRUE only one copy of this message should exist
void setUnique(BOOL val = TRUE) { mUnique = val; }
void setEditTextArgs(const LLSD& edit_args);
- void onClickIgnore(LLUICtrl* ctrl);
void onButtonPressed(const LLSD& data, S32 button);
private:
@@ -84,14 +82,18 @@ private:
struct ButtonData
{
+ ButtonData()
+ : mWidth(0)
+ {}
+
LLButton* mButton;
std::string mURL;
U32 mURLExternal;
+ S32 mWidth;
};
std::vector<ButtonData> mButtonData;
S32 mDefaultOption;
- LLCheckBoxCtrl* mCheck;
BOOL mCaution;
BOOL mUnique;
LLUIString mLabel;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index a2116817a2..024f25bc98 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -33,6 +33,7 @@
// library includes
#include "lldbstrings.h"
+#include "llcheckboxctrl.h"
#include "lllslconstants.h"
#include "llnotifications.h"
#include "lluiconstants.h"
@@ -55,7 +56,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images)
-: LLToastPanel(notification),
+: LLCheckBoxToastPanel(notification),
LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>(notification->getID())
{
init(rect, show_images);
@@ -162,6 +163,11 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair
{
left = (max_width - btn_rect.getWidth()) / 2;
}
+ else if (left == 0 && buttons.size() == 2)
+ {
+ // Note: this and "size() == 1" shouldn't be inside the cycle, might be good idea to refactor whole placing process
+ left = (max_width - (btn_rect.getWidth() * 2) - h_pad) / 2;
+ }
else if (left + btn_rect.getWidth() > max_width)// whether there is still some place for button+h_pad in the mControlPanel
{
// looks like we need to add button to the next row
@@ -381,9 +387,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
if (mIsScriptDialog)
{
// we are using default width for script buttons so we can determinate button_rows
- //to get a number of rows we divide the required width of the buttons to button_panel_width
- S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
- //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+ // to get a number of rows we divide the required width of the buttons to button_panel_width
+ // buttons.size() is reduced by -2 due to presence of ignore button which is calculated independently a bit lower
+ S32 button_rows = llceil(F32(buttons.size() - 2) * (BUTTON_WIDTH + h_pad) / (button_panel_width + h_pad));
//reserve one row for the ignore_btn
button_rows++;
//calculate required panel height for scripdialog notification.
@@ -409,7 +415,20 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
mInfoPanel->setFollowsAll();
- snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
+
+ // Add checkbox (one of couple types) if nessesary.
+ setCheckBoxes(HPAD * 2, 0, mInfoPanel);
+ if (mCheck)
+ {
+ mCheck->setFollows(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
+ }
+ // Snap to message, then to checkbox if present
+ snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
+ if (mCheck)
+ {
+ S32 new_panel_height = mCheck->getRect().getHeight() + getRect().getHeight() + VPAD;
+ reshape(getRect().getWidth(), new_panel_height);
+ }
// reshape the panel to its previous size
if (current_rect.notEmpty())
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index e4a75acfda..a5a637c6fa 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
* @deprecated this class will be removed after all toast panel types are
* implemented in separate classes.
*/
-class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
+class LLToastNotifyPanel: public LLCheckBoxToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
{
public:
/**
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 7c624d5b50..100d5ee713 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "lldbstrings.h"
+#include "llcheckboxctrl.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
@@ -34,6 +35,8 @@
#include "lltoastpanel.h"
#include "lltoastscriptquestion.h"
+#include <boost/algorithm/string.hpp>
+
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
// 'magic numbers', consider initializing (512+20) part from xml/notifications
@@ -145,3 +148,108 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
return res;
}
+
+LLCheckBoxToastPanel::LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf)
+: LLToastPanel(p_ntf),
+mCheck(NULL)
+{
+
+}
+
+void LLCheckBoxToastPanel::setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view)
+{
+ std::string ignore_label;
+ LLNotificationFormPtr form = mNotification->getForm();
+
+ if (form->getIgnoreType() == LLNotificationForm::IGNORE_CHECKBOX_ONLY)
+ {
+ // Normally text is only used to describe notification in preferences,
+ // but this one is not displayed in preferences and works on case by case
+ // basis.
+ // Display text if present, display 'always chose' if not.
+ std::string ignore_message = form->getIgnoreMessage();
+ if (ignore_message.empty())
+ {
+ ignore_message = LLNotifications::instance().getGlobalString("alwayschoose");
+ }
+ setCheckBox(ignore_message, ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+}
+
+bool LLCheckBoxToastPanel::setCheckBox(const std::string& check_title,
+ const std::string& check_control,
+ const commit_signal_t::slot_type& cb,
+ const S32 &h_pad,
+ const S32 &v_pad,
+ LLView *parent_view)
+{
+ mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
+
+ if (!mCheck)
+ {
+ return false;
+ }
+
+ const LLFontGL* font = mCheck->getFont();
+ const S32 LINE_HEIGHT = font->getLineHeight();
+
+ std::vector<std::string> lines;
+ boost::split(lines, check_title, boost::is_any_of("\n"));
+
+ // Extend dialog for "check next time"
+ S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * h_pad;
+ S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
+ max_msg_width = llmax(max_msg_width, check_width);
+ S32 dialog_width = max_msg_width + 2 * h_pad;
+
+ S32 dialog_height = LLToastPanel::getRect().getHeight();
+ dialog_height += LINE_HEIGHT * lines.size();
+ dialog_height += LINE_HEIGHT / 2;
+
+ LLToastPanel::reshape(dialog_width, dialog_height, FALSE);
+
+ S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
+
+ // set check_box's attributes
+ LLRect check_rect;
+ // if we are part of the toast, we need to leave space for buttons
+ S32 msg_y = v_pad + (parent_view ? 0 : (BTN_HEIGHT + LINE_HEIGHT / 2));
+ mCheck->setRect(check_rect.setOriginAndSize(msg_x, msg_y, max_msg_width, LINE_HEIGHT*lines.size()));
+ mCheck->setLabel(check_title);
+ mCheck->setCommitCallback(cb);
+
+ if (parent_view)
+ {
+ // assume that width and height autoadjusts to toast
+ parent_view->addChild(mCheck);
+ }
+ else
+ {
+ LLToastPanel::addChild(mCheck);
+ }
+
+ return true;
+}
+
+void LLCheckBoxToastPanel::onCommitCheckbox(LLUICtrl* ctrl)
+{
+ BOOL check = ctrl->getValue().asBoolean();
+ if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ mNotification->setIgnored(check);
+}
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 6a9b72a5ae..f4c758ade9 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -64,4 +64,23 @@ protected:
S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
};
+class LLCheckBoxCtrl;
+
+// Wrapper with support for 'don't ask again' checkbox
+class LLCheckBoxToastPanel : public LLToastPanel
+{
+public:
+ LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf);
+ virtual ~LLCheckBoxToastPanel() {};
+
+ // set checkboxes acording to defaults from form
+ void setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
+ // set single checkbox
+ bool setCheckBox(const std::string&, const std::string&, const commit_signal_t::slot_type& cb, const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
+protected:
+ void onCommitCheckbox(LLUICtrl* ctrl);
+
+ LLCheckBoxCtrl* mCheck;
+};
+
#endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index b5d78f3654..5235914c34 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -60,7 +60,7 @@ LLTool::~LLTool()
}
}
-BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
{
BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
@@ -83,9 +83,9 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
LL_INFOS() << "LLTool left mouse down" << LL_ENDL;
}
// by default, didn't handle it
+ // AGENT_CONTROL_LBUTTON_DOWN is handled by scanMouse() and scanKey()
// LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL;
- gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
- return TRUE;
+ return FALSE;
}
BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
@@ -95,8 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
LL_INFOS() << "LLTool left mouse up" << LL_ENDL;
}
// by default, didn't handle it
+ // AGENT_CONTROL_LBUTTON_UP is handled by scanMouse() and scanKey()
// LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL;
- gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
return TRUE;
}
@@ -115,6 +115,12 @@ BOOL LLTool::handleScrollWheel(S32 x, S32 y, S32 clicks)
return FALSE;
}
+BOOL LLTool::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ // by default, didn't handle it
+ return FALSE;
+}
+
BOOL LLTool::handleDoubleClick(S32 x,S32 y,MASK mask)
{
// LL_INFOS() << "LLTool::handleDoubleClick" << LL_ENDL;
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index c5bad9d532..41a38804ce 100644
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
@@ -49,7 +49,7 @@ public:
virtual BOOL isView() const { return FALSE; }
// Virtual functions inherited from LLMouseHandler
- virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
+ virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
@@ -57,6 +57,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index f66211ef34..50868d0fa5 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -270,7 +270,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
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));
- // TODO: animation on self could play it? edit it?
+ 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?
};
@@ -1626,6 +1627,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_CATEGORY:
+ case DAD_SETTINGS:
{
LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
@@ -1728,6 +1730,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
{
+ // Legacy
return ACCEPT_NO;
}
@@ -2154,6 +2157,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
{
+ // Legacy
return ACCEPT_NO;
}
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index a4806ceaf6..f01b374db1 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -142,8 +142,9 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
// call the base class to propogate info to sim
LLTool::handleMouseDown(x, y, mask);
-
- if (!gAgent.leftButtonGrabbed())
+
+ // leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account
+ if (!gAgent.leftButtonGrabbed() || ((mask & DEFAULT_GRAB_MASK) != 0 && !gAgentCamera.cameraMouselook()))
{
// can grab transparent objects (how touch event propagates, scripters rely on this)
gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h
index 02ed5c26d7..ce0de0f946 100644
--- a/indra/newview/lltoolgrab.h
+++ b/indra/newview/lltoolgrab.h
@@ -44,6 +44,7 @@ class LLPickInfo;
void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset);
void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick);
+const MASK DEFAULT_GRAB_MASK = MASK_CONTROL;
/**
* LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index 6c9155be85..9539081f30 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -107,11 +107,18 @@ BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask)
if (gSavedSettings.getBOOL("MouseSun"))
{
- gSky.setSunDirection(LLViewerCamera::getInstance()->getAtAxis(), LLVector3(0.f, 0.f, 0.f));
- gSky.setOverrideSun(TRUE);
+ LLVector3 sunpos = LLViewerCamera::getInstance()->getAtAxis();
+ gSky.setSunDirectionCFR(sunpos);
gSavedSettings.setVector3("SkySunDefaultPosition", LLViewerCamera::getInstance()->getAtAxis());
}
+ if (gSavedSettings.getBOOL("MouseMoon"))
+ {
+ LLVector3 moonpos = LLViewerCamera::getInstance()->getAtAxis();
+ gSky.setMoonDirectionCFR(moonpos);
+ gSavedSettings.setVector3("SkyMoonDefaultPosition", LLViewerCamera::getInstance()->getAtAxis());
+ }
+
gViewerWindow->moveCursorToCenter();
gViewerWindow->hideCursor();
}
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index f6eb290bc3..3fcf193dec 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -355,7 +355,7 @@ bool LLToolMgr::inBuildMode()
bool LLToolMgr::canAccessMarketplace()
{
- return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT) || gSavedSettings.getBOOL("InventoryOutboxDisplayBoth");
+ return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
void LLToolMgr::toggleMarketplace(const LLSD& sdname)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 3955d7a72f..322d0bc727 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -63,6 +63,7 @@
#include "llviewerobject.h"
#include "llviewerparcelmgr.h"
#include "llviewerwindow.h"
+#include "llviewerinput.h"
#include "llviewermedia.h"
#include "llvoavatarself.h"
#include "llviewermediafocus.h"
@@ -83,7 +84,6 @@ LLToolPie::LLToolPie()
mMouseOutsideSlop( false ),
mMouseSteerX(-1),
mMouseSteerY(-1),
- mBlockClickToWalk(false),
mClickAction(0),
mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ),
@@ -91,7 +91,7 @@ LLToolPie::LLToolPie()
{
}
-BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
{
BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
@@ -172,10 +172,8 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mPick.mKeyMask = mask;
mMouseButtonDown = true;
-
- handleLeftClickPick();
- return TRUE;
+ return handleLeftClickPick();
}
// Spawn context menus on right mouse down so you can drag over and select
@@ -203,9 +201,31 @@ BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask)
return LLTool::handleRightMouseUp(x, y, mask);
}
+BOOL LLToolPie::handleScrollWheelAny(S32 x, S32 y, S32 clicks_x, S32 clicks_y)
+{
+ BOOL res = FALSE;
+ // mHoverPick should have updated on its own and we should have a face
+ // in LLViewerMediaFocus in case of media, so just reuse mHoverPick
+ if (mHoverPick.mUVCoords.mV[VX] >= 0.f && mHoverPick.mUVCoords.mV[VY] >= 0.f)
+ {
+ res = LLViewerMediaFocus::getInstance()->handleScrollWheel(mHoverPick.mUVCoords, clicks_x, clicks_y);
+ }
+ else
+ {
+ // this won't provide correct coordinates in case of object selection
+ res = LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks_x, clicks_y);
+ }
+ return res;
+}
+
BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
+ return handleScrollWheelAny(x, y, 0, clicks);
+}
+
+BOOL LLToolPie::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ return handleScrollWheelAny(x, y, clicks, 0);
}
// True if you selected an object.
@@ -369,8 +389,6 @@ BOOL LLToolPie::handleLeftClickPick()
// put focus back "in world"
if (gFocusMgr.getKeyboardFocus())
{
- // don't click to walk on attempt to give focus to world
- mBlockClickToWalk = true;
gFocusMgr.setKeyboardFocus(NULL);
}
@@ -414,7 +432,7 @@ BOOL LLToolPie::handleLeftClickPick()
}
object = (LLViewerObject*)object->getParent();
}
- if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk"))
+ if (object && object == gAgentAvatarp)
{
// we left clicked on avatar, switch to focus mode
mMouseButtonDown = false;
@@ -431,7 +449,6 @@ BOOL LLToolPie::handleLeftClickPick()
// LLFirstUse::useLeftClickNoHit();
/////////
- // Eat the event
return LLTool::handleMouseDown(x, y, mask);
}
@@ -538,17 +555,120 @@ void LLToolPie::resetSelection()
mClickAction = 0;
}
-void LLToolPie::walkToClickedLocation()
+bool LLToolPie::walkToClickedLocation()
+{
+ if (gAgent.getFlying() // don't auto-navigate while flying until that works
+ || !gAgentAvatarp
+ || gAgentAvatarp->isSitting())
+ {
+ return false;
+ }
+
+ LLPickInfo saved_pick = mPick;
+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+ {
+ mPick = gViewerWindow->pickImmediate(mHoverPick.mMousePt.mX, mHoverPick.mMousePt.mY,
+ FALSE /* ignore transparent */,
+ FALSE /* ignore rigged */,
+ FALSE /* ignore particles */);
+ }
+ else
+ {
+ // We do not handle hover in mouselook as we do in other modes, so
+ // use croshair's position to do a pick
+ mPick = gViewerWindow->pickImmediate(gViewerWindow->getWorldViewRectScaled().getWidth() / 2,
+ gViewerWindow->getWorldViewRectScaled().getHeight() / 2,
+ FALSE /* ignore transparent */,
+ FALSE /* ignore rigged */,
+ FALSE /* ignore particles */);
+ }
+
+ if (mPick.mPickType == LLPickInfo::PICK_OBJECT)
+ {
+ if (mPick.getObject() && mPick.getObject()->isHUDAttachment())
+ {
+ mPick = saved_pick;
+ return false;
+ }
+ }
+
+ LLViewerObject* avatar_object = mPick.getObject();
+
+ // get pointer to avatar
+ while (avatar_object && !avatar_object->isAvatar())
+ {
+ avatar_object = (LLViewerObject*)avatar_object->getParent();
+ }
+
+ if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
+ {
+ const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
+ // pretend we picked some point a bit in front of avatar
+ mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
+ }
+
+ if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
+ (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()))
+ {
+ gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
+
+ if (mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
+ mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
+ mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
+ mAutoPilotDestination->setPixelSize(5);
+ mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
+ mAutoPilotDestination->setDuration(3.f);
+
+ LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
+ gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE);
+ LLFirstUse::notMoving(false);
+ showVisualContextMenuEffect();
+ return true;
+ }
+ else
+ {
+ LL_DEBUGS() << "walk target was "
+ << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero")
+ << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land")
+ << ", pick object was " << mPick.mObjectID
+ << LL_ENDL;
+ mPick = saved_pick;
+ return false;
+ }
+ return true;
+}
+
+bool LLToolPie::teleportToClickedLocation()
{
- if(mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
- mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
- mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
- mAutoPilotDestination->setPixelSize(5);
- mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
- mAutoPilotDestination->setDuration(3.f);
-
- LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
- gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE);
+ if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ {
+ // We do not handle hover in mouselook as we do in other modes, so
+ // use croshair's position to do a pick
+ BOOL pick_rigged = false;
+ mHoverPick = gViewerWindow->pickImmediate(gViewerWindow->getWorldViewRectScaled().getWidth() / 2,
+ gViewerWindow->getWorldViewRectScaled().getHeight() / 2,
+ FALSE,
+ pick_rigged);
+ }
+ LLViewerObject* objp = mHoverPick.getObject();
+ LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
+
+ bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
+ bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND;
+ bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero();
+ bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
+ bool has_click_action = final_click_action(objp);
+
+ if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
+ {
+ LLVector3d pos = mHoverPick.mPosGlobal;
+ pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
+ gAgent.teleportViaLocationLookAt(pos);
+ mPick = mHoverPick;
+ showVisualContextMenuEffect();
+ return true;
+ }
+ return false;
}
// When we get object properties after left-clicking on an object
@@ -624,8 +744,9 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
}
else if (!mMouseOutsideSlop
- && mMouseButtonDown
- && gSavedSettings.getBOOL("ClickToWalk"))
+ && mMouseButtonDown
+ // disable camera steering if click on land is not used for moving
+ && gViewerInput.isMouseBindUsed(CLICK_LEFT))
{
S32 delta_x = x - mMouseDownX;
S32 delta_y = y - mMouseDownY;
@@ -649,7 +770,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
else
{
// perform a separate pick that detects transparent objects since they respond to 1-click actions
- LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+ LLPickInfo click_action_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
LLViewerObject* click_action_object = click_action_pick.getObject();
@@ -710,70 +831,10 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
mDoubleClickTimer.reset();
}
LLViewerObject* obj = mPick.getObject();
- U8 click_action = final_click_action(obj);
- // let media have first pass at click
- if (handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus())
- {
- mBlockClickToWalk = true;
- }
stopCameraSteering();
mMouseButtonDown = false;
- if (click_action == CLICK_ACTION_NONE // not doing 1-click action
- && gSavedSettings.getBOOL("ClickToWalk") // click to walk enabled
- && !gAgent.getFlying() // don't auto-navigate while flying until that works
- && gAgentAvatarp
- && !gAgentAvatarp->isSitting()
- && !mBlockClickToWalk // another behavior hasn't cancelled click to walk
- )
- {
- // We may be doing click to walk, but we don't want to use a target on
- // a transparent object because the user thought they were clicking on
- // whatever they were seeing through it, so recompute what was clicked on
- // ignoring transparent objects
- LLPickInfo savedPick = mPick;
- mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
- FALSE /* ignore transparent */,
- FALSE /* ignore rigged */,
- FALSE /* ignore particles */);
-
- if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
- && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land
- || mPick.mObjectID.notNull())) // or on an object
- {
- // handle special cases of steering picks
- LLViewerObject* avatar_object = mPick.getObject();
-
- // get pointer to avatar
- while (avatar_object && !avatar_object->isAvatar())
- {
- avatar_object = (LLViewerObject*)avatar_object->getParent();
- }
-
- if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
- {
- const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
- // pretend we picked some point a bit in front of avatar
- mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
- }
- gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
- walkToClickedLocation();
- LLFirstUse::notMoving(false);
-
- return TRUE;
- }
- else
- {
- LL_DEBUGS("maint5901") << "walk target was "
- << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero")
- << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land")
- << ", pick object was " << mPick.mObjectID
- << LL_ENDL;
- // we didn't click to walk, so restore the original target
- mPick = savedPick;
- }
- }
gViewerWindow->setCursor(UI_CURSOR_ARROW);
if (hasMouseCapture())
{
@@ -783,7 +844,6 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
LLToolMgr::getInstance()->clearTransientTool();
gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
- mBlockClickToWalk = false;
return LLTool::handleMouseUp(x, y, mask);
}
@@ -809,66 +869,13 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
- if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f))
+ if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f))
{
mDoubleClickTimer.stop();
return FALSE;
}
mDoubleClickTimer.stop();
- if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
- {
- // We may be doing double click to walk, but we don't want to use a target on
- // a transparent object because the user thought they were clicking on
- // whatever they were seeing through it, so recompute what was clicked on
- // ignoring transparent objects
- LLPickInfo savedPick = mPick;
- mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
- FALSE /* ignore transparent */,
- FALSE /* ignore rigged */,
- FALSE /* ignore particles */);
-
- if(mPick.mPickType == LLPickInfo::PICK_OBJECT)
- {
- if (mPick.getObject() && mPick.getObject()->isHUDAttachment())
- {
- mPick = savedPick;
- return FALSE;
- }
- }
-
- if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
- (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()))
- {
- walkToClickedLocation();
- return TRUE;
- }
- else
- {
- // restore the original pick for any other purpose
- mPick = savedPick;
- }
- }
- else if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- LLViewerObject* objp = mPick.getObject();
- LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
-
- bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
- bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND;
- bool pos_non_zero = !mPick.mPosGlobal.isExactlyZero();
- bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
- bool has_click_action = final_click_action(objp);
-
- if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
- {
- LLVector3d pos = mPick.mPosGlobal;
- pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
- gAgent.teleportViaLocationLookAt(pos);
- return TRUE;
- }
- }
-
return FALSE;
}
@@ -1400,7 +1407,6 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info)
void LLToolPie::handleSelect()
{
// tool is reselected when app gets focus, etc.
- mBlockClickToWalk = true;
}
void LLToolPie::handleDeselect()
@@ -1427,7 +1433,7 @@ LLTool* LLToolPie::getOverrideTool(MASK mask)
{
if (gSavedSettings.getBOOL("EnableGrab"))
{
- if (mask == MASK_CONTROL)
+ if (mask == DEFAULT_GRAB_MASK)
{
return LLToolGrab::getInstance();
}
@@ -1461,7 +1467,7 @@ void LLToolPie::stopCameraSteering()
bool LLToolPie::inCameraSteerMode()
{
- return mMouseButtonDown && mMouseOutsideSlop && gSavedSettings.getBOOL("ClickToWalk");
+ return mMouseButtonDown && mMouseOutsideSlop;
}
// true if x,y outside small box around start_x,start_y
@@ -1912,7 +1918,6 @@ void LLToolPie::startCameraSteering()
{
LLFirstUse::notMoving(false);
mMouseOutsideSlop = true;
- mBlockClickToWalk = true;
if (gAgentCamera.getFocusOnAvatar())
{
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 95d155a474..8f6100e4b4 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -42,14 +42,16 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
public:
// Virtual functions inherited from LLMouseHandler
- virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
+ virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ BOOL handleScrollWheelAny(S32 x, S32 y, S32 clicks_x, S32 clicks_y);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
virtual void render();
@@ -66,8 +68,8 @@ public:
LLViewerObject* getClickActionObject() { return mClickActionObject; }
LLObjectSelection* getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; }
void resetSelection();
- void walkToClickedLocation();
- void blockClickToWalk() { mBlockClickToWalk = true; }
+ bool walkToClickedLocation();
+ bool teleportToClickedLocation();
void stopClickToWalk();
static void selectionPropertiesReceived();
@@ -109,7 +111,6 @@ private:
LLPointer<LLHUDEffectBlob> mAutoPilotDestination;
LLPointer<LLHUDEffectBlob> mMouseSteerGrabPoint;
bool mClockwise;
- bool mBlockClickToWalk;
LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 2ec5c41b88..728d0c9417 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -570,8 +570,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar());
}
- LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor();
- LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getFogColor();
+ LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getSkyFogColor();
+ LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getSkyFogColor();
F32 FADE_DIST = 3.f;
fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST));
diff --git a/indra/newview/lltrackpicker.cpp b/indra/newview/lltrackpicker.cpp
new file mode 100644
index 0000000000..fe6256a8a9
--- /dev/null
+++ b/indra/newview/lltrackpicker.cpp
@@ -0,0 +1,134 @@
+/**
+* @author AndreyK Productengine
+* @brief LLTrackPicker class header file including related functions
+*
+* $LicenseInfo:firstyear=2018&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2018, 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 "lltrackpicker.h"
+
+#include "llradiogroup.h"
+#include "llviewercontrol.h"
+
+
+//=========================================================================
+namespace
+{
+ const std::string FLOATER_DEFINITION_XML("floater_pick_track.xml");
+
+ const std::string BTN_SELECT("btn_select");
+ const std::string BTN_CANCEL("btn_cancel");
+ const std::string RDO_TRACK_SELECTION("track_selection");
+ const std::string RDO_TRACK_PREFIX("radio_sky");
+}
+//=========================================================================
+
+LLFloaterTrackPicker::LLFloaterTrackPicker(LLView * owner, const LLSD &params) :
+ LLFloater(params),
+ mContextConeOpacity(0.0f),
+ mOwnerHandle()
+{
+ mOwnerHandle = owner->getHandle();
+ buildFromFile(FLOATER_DEFINITION_XML);
+}
+
+LLFloaterTrackPicker::~LLFloaterTrackPicker()
+{
+}
+
+BOOL LLFloaterTrackPicker::postBuild()
+{
+ childSetAction(BTN_CANCEL, [this](LLUICtrl*, const LLSD& param){ onButtonCancel(); });
+ childSetAction(BTN_SELECT, [this](LLUICtrl*, const LLSD& param){ onButtonSelect(); });
+ return TRUE;
+}
+
+void LLFloaterTrackPicker::onClose(bool app_quitting)
+{
+ if (app_quitting)
+ return;
+
+ LLView *owner = mOwnerHandle.get();
+ if (owner)
+ {
+ owner->setFocus(TRUE);
+ }
+}
+
+void LLFloaterTrackPicker::showPicker(const LLSD &args)
+{
+ LLSD::array_const_iterator iter;
+ LLSD::array_const_iterator end = args.endArray();
+
+ bool select_item = true;
+ for (iter = args.beginArray(); iter != end; ++iter)
+ {
+ S32 track_id = (*iter)["id"].asInteger();
+ bool can_enable = (*iter)["enabled"].asBoolean();
+ LLCheckBoxCtrl *view = getChild<LLCheckBoxCtrl>(RDO_TRACK_PREFIX + llformat("%d", track_id), true);
+ view->setEnabled(can_enable);
+ view->setLabelArg("[ALT]", (*iter).has("altitude") ? ((*iter)["altitude"].asString() + "m") : " ");
+
+ // Mark first avaliable item as selected
+ if (can_enable && select_item)
+ {
+ select_item = false;
+ getChild<LLRadioGroup>(RDO_TRACK_SELECTION, true)->setSelectedByValue(LLSD(track_id), TRUE);
+ }
+ }
+
+ openFloater(getKey());
+ setFocus(TRUE);
+}
+
+void LLFloaterTrackPicker::draw()
+{
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterTrackPicker::onButtonCancel()
+{
+ closeFloater();
+}
+
+void LLFloaterTrackPicker::onButtonSelect()
+{
+ if (mCommitSignal)
+ {
+ (*mCommitSignal)(this, getChild<LLRadioGroup>(RDO_TRACK_SELECTION, true)->getSelectedValue());
+ }
+ closeFloater();
+}
+
+void LLFloaterTrackPicker::onFocusLost()
+{
+ if (isInVisibleChain())
+ {
+ closeFloater();
+ }
+}
diff --git a/indra/newview/lltrackpicker.h b/indra/newview/lltrackpicker.h
new file mode 100644
index 0000000000..dab3b72915
--- /dev/null
+++ b/indra/newview/lltrackpicker.h
@@ -0,0 +1,58 @@
+/**
+ * @file lltrackpicker.h
+ * @author AndreyK Productengine
+ * @brief LLTrackPicker class header file including related functions
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, 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_TRACKPICKER_H
+#define LL_TRACKPICKER_H
+
+#include "llfloater.h"
+
+
+//=========================================================================
+
+class LLFloaterTrackPicker : public LLFloater
+{
+public:
+ LLFloaterTrackPicker(LLView * owner, const LLSD &params = LLSD());
+ virtual ~LLFloaterTrackPicker() override;
+
+ virtual BOOL postBuild() override;
+ virtual void onClose(bool app_quitting) override;
+ void showPicker(const LLSD &args);
+
+ virtual void draw() override;
+
+ void onButtonCancel();
+ void onButtonSelect();
+
+private:
+ void onFocusLost() override;
+
+ F32 mContextConeOpacity;
+ LLHandle<LLView> mOwnerHandle;
+};
+
+#endif // LL_TRACKPICKER_H
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index e424983cf8..fa3b44f702 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -134,11 +134,11 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel().c_str(),
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
@@ -177,11 +177,11 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel().c_str(),
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 15c3dad38e..77e950a1c9 100644
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -53,7 +53,7 @@ public:
virtual ~LLWholeModelFeeObserver() {}
virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
- virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason) = 0;
+ virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason, const LLSD& result) = 0;
LLHandle<LLWholeModelFeeObserver> getWholeModelFeeObserverHandle() const { return mWholeModelFeeObserverHandle; }
diff --git a/indra/newview/llurlfloaterdispatchhandler.cpp b/indra/newview/llurlfloaterdispatchhandler.cpp
new file mode 100644
index 0000000000..6b1a373beb
--- /dev/null
+++ b/indra/newview/llurlfloaterdispatchhandler.cpp
@@ -0,0 +1,214 @@
+/**
+ * @file llurlfloaterdispatchhandler.cpp
+ * @brief Handles URLFloater generic message from server
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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 "llurlfloaterdispatchhandler.h"
+
+#include "llfloaterreg.h"
+#include "llfloaterhowto.h"
+#include "llfloaterwebcontent.h"
+#include "llsdserialize.h"
+#include "llviewercontrol.h"
+#include "llviewergenericmessage.h"
+#include "llweb.h"
+
+// Example:
+// llOpenFloater("guidebook", "http://page.com", []);
+
+// values specified by server side's dispatcher
+// for llopenfloater
+const std::string MESSAGE_URL_FLOATER("URLFloater");
+const std::string KEY_ACTION("action"); // "action" will be the string constant "OpenURL"
+const std::string VALUE_OPEN_URL("OpenURL");
+const std::string KEY_DATA("action_data");
+const std::string KEY_FLOATER("floater_title"); // name of the floater, not title
+const std::string KEY_URL("floater_url");
+const std::string KEY_PARAMS("floater_params");
+
+// Supported floaters
+const std::string FLOATER_GUIDEBOOK("guidebook");
+const std::string FLOATER_HOW_TO("how_to"); // alias for guidebook
+const std::string FLOATER_WEB_CONTENT("web_content");
+
+// All arguments are palceholders! Server side will need to add validation first.
+// Web content universal argument
+const std::string KEY_TRUSTED_CONTENT("trusted_content");
+
+// Guidebook specific arguments
+const std::string KEY_WIDTH("width");
+const std::string KEY_HEGHT("height");
+const std::string KEY_CAN_CLOSE("can_close");
+const std::string KEY_TITLE("title");
+
+// web_content specific arguments
+const std::string KEY_SHOW_PAGE_TITLE("show_page_title");
+const std::string KEY_ALLOW_ADRESS_ENTRY("allow_address_entry"); // It is not recomended to set this to true if trusted content is allowed
+
+
+LLUrlFloaterDispatchHandler LLUrlFloaterDispatchHandler::sUrlDispatchhandler;
+
+LLUrlFloaterDispatchHandler::LLUrlFloaterDispatchHandler()
+{
+}
+
+LLUrlFloaterDispatchHandler::~LLUrlFloaterDispatchHandler()
+{
+}
+
+void LLUrlFloaterDispatchHandler::registerInDispatcher()
+{
+ if (!gGenericDispatcher.isHandlerPresent(MESSAGE_URL_FLOATER))
+ {
+ gGenericDispatcher.addHandler(MESSAGE_URL_FLOATER, &sUrlDispatchhandler);
+ }
+}
+
+//virtual
+bool LLUrlFloaterDispatchHandler::operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings)
+{
+ // invoice - transaction id
+
+ 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("URLFloater") << "Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ return false;
+ }
+ }
+
+ // At the moment command_params is a placeholder and code treats it as map
+ // Once server side adds argument validation this will be either a map or an array
+ std::string floater;
+ LLSD command_params;
+ std::string url;
+
+ if (message.has(KEY_ACTION) && message[KEY_ACTION].asString() == VALUE_OPEN_URL)
+ {
+ LLSD &action_data = message[KEY_DATA];
+ if (action_data.isMap())
+ {
+ floater = action_data[KEY_FLOATER].asString();
+ command_params = action_data[KEY_PARAMS];
+ url = action_data[KEY_URL].asString();
+ }
+ }
+ else if (message.has(KEY_FLOATER))
+ {
+ floater = message[KEY_FLOATER].asString();
+ command_params = message[KEY_PARAMS];
+ url = message[KEY_URL].asString();
+ }
+ else
+ {
+ LL_WARNS("URLFloater") << "Received " << MESSAGE_URL_FLOATER << " with unexpected data format: " << message << LL_ENDL;
+ return false;
+ }
+
+ if (url.find("://") == std::string::npos)
+ {
+ // try unescaping
+ url = LLURI::unescape(url);
+ }
+
+ LLFloaterWebContent::Params params;
+ params.url = url;
+
+ if (floater == FLOATER_GUIDEBOOK || floater == FLOATER_HOW_TO)
+ {
+ LL_DEBUGS("URLFloater") << "Opening how_to floater with parameters: " << message << LL_ENDL;
+ if (command_params.isMap()) // by default is undefines
+ {
+ params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false;
+
+ // Script's side argument list can't include other lists, neither
+ // there is a LLRect type, so expect just width and height
+ if (command_params.has(KEY_WIDTH) && command_params.has(KEY_HEGHT))
+ {
+ LLRect rect(0, command_params[KEY_HEGHT].asInteger(), command_params[KEY_WIDTH].asInteger(), 0);
+ params.preferred_media_size.setValue(rect);
+ }
+ }
+
+ // Some locations will have customized guidebook, which this function easists for
+ // only one instance of guidebook can exist at a time, so if this command arrives,
+ // we need to close previous guidebook then reopen it.
+
+ LLFloater* instance = LLFloaterReg::findInstance("guidebook");
+ if (instance)
+ {
+ instance->closeHostedFloater();
+ }
+
+ LLFloaterReg::toggleInstanceOrBringToFront("guidebook", params);
+
+ if (command_params.isMap())
+ {
+ LLFloater* instance = LLFloaterReg::findInstance("guidebook");
+ if (command_params.has(KEY_CAN_CLOSE))
+ {
+ instance->setCanClose(command_params[KEY_CAN_CLOSE].asBoolean());
+ }
+ if (command_params.has(KEY_TITLE))
+ {
+ instance->setTitle(command_params[KEY_TITLE].asString());
+ }
+ }
+ }
+ else if (floater == FLOATER_WEB_CONTENT)
+ {
+ LL_DEBUGS("URLFloater") << "Opening web_content floater with parameters: " << message << LL_ENDL;
+ if (command_params.isMap()) // by default is undefines, might be better idea to init params from command_params
+ {
+ params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false;
+ params.show_page_title = command_params.has(KEY_SHOW_PAGE_TITLE) ? command_params[KEY_SHOW_PAGE_TITLE].asBoolean() : true;
+ params.allow_address_entry = command_params.has(KEY_ALLOW_ADRESS_ENTRY) ? command_params[KEY_ALLOW_ADRESS_ENTRY].asBoolean() : true;
+ }
+ LLFloaterReg::showInstance("web_content", params);
+ }
+ else
+ {
+ LL_DEBUGS("URLFloater") << "Unknow floater with parameters: " << message << LL_ENDL;
+ if (LLFloaterReg::isRegistered(floater))
+ {
+ // A valid floater
+ LL_INFOS("URLFloater") << "Floater " << floater << " is not supported by llopenfloater or URLFloater" << LL_ENDL;
+ }
+ else
+ {
+ // A valid message, but no such flaoter
+ LL_WARNS("URLFloater") << "Recieved a command to open unknown floater: " << floater << LL_ENDL;
+ }
+ }
+
+ return true;
+}
diff --git a/indra/newview/llurlfloaterdispatchhandler.h b/indra/newview/llurlfloaterdispatchhandler.h
new file mode 100644
index 0000000000..1dff52c66f
--- /dev/null
+++ b/indra/newview/llurlfloaterdispatchhandler.h
@@ -0,0 +1,49 @@
+/**
+ * @file llurlfloaterdispatchhandler.h
+ * @brief Handles URLFloater generic message from server
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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
+ * 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_LLURLFLOATERDISPATCHHANDLER_H
+#define LL_LLURLFLOATERDISPATCHHANDLER_H
+
+#include "lldispatcher.h"
+
+class LLUrlFloaterDispatchHandler : public LLDispatchHandler
+{
+public:
+ LOG_CLASS(LLUrlFloaterDispatchHandler);
+
+ LLUrlFloaterDispatchHandler();
+ virtual ~LLUrlFloaterDispatchHandler();
+
+ virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override;
+
+ static void registerInDispatcher();
+
+private:
+ static LLUrlFloaterDispatchHandler sUrlDispatchhandler;
+};
+
+#endif // LL_LLURLFLOATERDISPATCHHANDLER_H
+
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 4e07223784..4720a989b0 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -26,9 +26,10 @@
*/
#include "llviewerprecompiledheaders.h"
-#include <iostream>
-#include <sstream>
+#include "llevents.h"
+#include "lleventfilter.h"
#include "llversioninfo.h"
+#include "stringize.h"
#include <boost/regex.hpp>
#if ! defined(LL_VIEWER_CHANNEL) \
@@ -43,100 +44,90 @@
// Set the version numbers in indra/VIEWER_VERSION
//
-//static
+LLVersionInfo::LLVersionInfo():
+ short_version(STRINGIZE(LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH)),
+ // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
+ // macro expands to the string name of the channel, but without quotes. We
+ // need to turn it into a quoted string. LL_TO_STRING() does that.
+ mWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL)),
+ build_configuration(LLBUILD_CONFIG), // set in indra/cmake/BuildVersion.cmake
+ // instantiate an LLEventMailDrop with canonical name to listen for news
+ // from SLVersionChecker
+ mPump{new LLEventMailDrop("relnotes")},
+ // immediately listen on mPump, store arriving URL into mReleaseNotes
+ mStore{new LLStoreListener<std::string>(*mPump, mReleaseNotes)}
+{
+}
+
+void LLVersionInfo::initSingleton()
+{
+ // We override initSingleton() not because we have dependencies on other
+ // LLSingletons, but because certain initializations call other member
+ // functions. We should refrain from calling methods until this object is
+ // fully constructed; such calls don't really belong in the constructor.
+
+ // cache the version string
+ version = STRINGIZE(getShortVersion() << "." << getBuild());
+}
+
+LLVersionInfo::~LLVersionInfo()
+{
+}
+
S32 LLVersionInfo::getMajor()
{
return LL_VIEWER_VERSION_MAJOR;
}
-//static
S32 LLVersionInfo::getMinor()
{
return LL_VIEWER_VERSION_MINOR;
}
-//static
S32 LLVersionInfo::getPatch()
{
return LL_VIEWER_VERSION_PATCH;
}
-//static
S32 LLVersionInfo::getBuild()
{
return LL_VIEWER_VERSION_BUILD;
}
-//static
-const std::string &LLVersionInfo::getVersion()
+std::string LLVersionInfo::getVersion()
{
- static std::string version("");
- if (version.empty())
- {
- std::ostringstream stream;
- stream << LLVersionInfo::getShortVersion() << "." << LLVersionInfo::getBuild();
- // cache the version string
- version = stream.str();
- }
return version;
}
-//static
-const std::string &LLVersionInfo::getShortVersion()
+std::string LLVersionInfo::getShortVersion()
{
- static std::string short_version("");
- if(short_version.empty())
- {
- // cache the version string
- std::ostringstream stream;
- stream << LL_VIEWER_VERSION_MAJOR << "."
- << LL_VIEWER_VERSION_MINOR << "."
- << LL_VIEWER_VERSION_PATCH;
- short_version = stream.str();
- }
return short_version;
}
-namespace
-{
- // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
- // macro expands to the string name of the channel, but without quotes. We
- // need to turn it into a quoted string. LL_TO_STRING() does that.
- /// Storage of the channel name the viewer is using.
- // The channel name is set by hardcoded constant,
- // or by calling LLVersionInfo::resetChannel()
- std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL));
-
- // Storage for the "version and channel" string.
- // This will get reset too.
- std::string sVersionChannel("");
-}
-
-//static
-const std::string &LLVersionInfo::getChannelAndVersion()
+std::string LLVersionInfo::getChannelAndVersion()
{
- if (sVersionChannel.empty())
+ if (mVersionChannel.empty())
{
// cache the version string
- sVersionChannel = LLVersionInfo::getChannel() + " " + LLVersionInfo::getVersion();
+ mVersionChannel = getChannel() + " " + getVersion();
}
- return sVersionChannel;
+ return mVersionChannel;
}
-//static
-const std::string &LLVersionInfo::getChannel()
+std::string LLVersionInfo::getChannel()
{
- return sWorkingChannelName;
+ return mWorkingChannelName;
}
void LLVersionInfo::resetChannel(const std::string& channel)
{
- sWorkingChannelName = channel;
- sVersionChannel.clear(); // Reset version and channel string til next use.
+ mWorkingChannelName = channel;
+ mVersionChannel.clear(); // Reset version and channel string til next use.
}
-//static
LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()
{
ViewerMaturity maturity;
@@ -175,8 +166,12 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()
}
-const std::string &LLVersionInfo::getBuildConfig()
+std::string LLVersionInfo::getBuildConfig()
{
- static const std::string build_configuration(LLBUILD_CONFIG); // set in indra/cmake/BuildVersion.cmake
return build_configuration;
}
+
+std::string LLVersionInfo::getReleaseNotes()
+{
+ return mReleaseNotes;
+}
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index b8b4341385..02ff0c094a 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -28,8 +28,14 @@
#ifndef LL_LLVERSIONINFO_H
#define LL_LLVERSIONINFO_H
-#include <string>
#include "stdtypes.h"
+#include "llsingleton.h"
+#include <string>
+#include <memory>
+
+class LLEventMailDrop;
+template <typename T>
+class LLStoreListener;
///
/// This API provides version information for the viewer. This
@@ -38,42 +44,46 @@
/// viewer code that wants to query the current version should
/// use this API.
///
-class LLVersionInfo
+class LLVersionInfo: public LLSingleton<LLVersionInfo>
{
+ LLSINGLETON(LLVersionInfo);
+ void initSingleton();
public:
- /// return the major verion number as an integer
- static S32 getMajor();
+ ~LLVersionInfo();
- /// return the minor verion number as an integer
- static S32 getMinor();
+ /// return the major version number as an integer
+ S32 getMajor();
- /// return the patch verion number as an integer
- static S32 getPatch();
+ /// return the minor version number as an integer
+ S32 getMinor();
+
+ /// return the patch version number as an integer
+ S32 getPatch();
/// return the build number as an integer
- static S32 getBuild();
+ S32 getBuild();
/// return the full viewer version as a string like "2.0.0.200030"
- static const std::string &getVersion();
+ std::string getVersion();
/// return the viewer version as a string like "2.0.0"
- static const std::string &getShortVersion();
+ std::string getShortVersion();
/// return the viewer version and channel as a string
/// like "Second Life Release 2.0.0.200030"
- static const std::string &getChannelAndVersion();
+ std::string getChannelAndVersion();
/// return the channel name, e.g. "Second Life"
- static const std::string &getChannel();
+ std::string getChannel();
/// return the CMake build type
- static const std::string &getBuildConfig();
+ std::string getBuildConfig();
/// reset the channel name used by the viewer.
- static void resetChannel(const std::string& channel);
+ void resetChannel(const std::string& channel);
/// return the bit width of an address
- static const S32 getAddressSize() { return ADDRESS_SIZE; }
+ S32 getAddressSize() { return ADDRESS_SIZE; }
typedef enum
{
@@ -82,7 +92,31 @@ public:
BETA_VIEWER,
RELEASE_VIEWER
} ViewerMaturity;
- static ViewerMaturity getViewerMaturity();
+ ViewerMaturity getViewerMaturity();
+
+ /// get the release-notes URL, once it becomes available -- until then,
+ /// return empty string
+ std::string getReleaseNotes();
+
+private:
+ std::string version;
+ std::string short_version;
+ /// Storage of the channel name the viewer is using.
+ // The channel name is set by hardcoded constant,
+ // or by calling resetChannel()
+ std::string mWorkingChannelName;
+ // Storage for the "version and channel" string.
+ // This will get reset too.
+ std::string mVersionChannel;
+ std::string build_configuration;
+ std::string mReleaseNotes;
+ // Store unique_ptrs to the next couple things so we don't have to explain
+ // to every consumer of this header file all the details of each.
+ // mPump is the LLEventMailDrop on which we listen for SLVersionChecker to
+ // post the release-notes URL from the Viewer Version Manager.
+ std::unique_ptr<LLEventMailDrop> mPump;
+ // mStore is an adapter that stores the release-notes URL in mReleaseNotes.
+ std::unique_ptr<LLStoreListener<std::string>> mStore;
};
#endif
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index e0b64403ef..7842d24279 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -49,6 +49,9 @@
/// LLViewerAssetRequest
///----------------------------------------------------------------------------
+ // There is also PoolSizeAssetStorage value in setting that should mirror this name
+static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage";
+
/**
* @brief Local class to encapsulate asset fetch requests with a timestamp.
*
@@ -127,6 +130,23 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
{
}
+LLViewerAssetStorage::~LLViewerAssetStorage()
+{
+ if (!LLCoprocedureManager::wasDeleted())
+ {
+ // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later.
+ LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL);
+ }
+
+ while (mCoroWaitList.size() > 0)
+ {
+ CoroWaitList &request = mCoroWaitList.front();
+ // Clean up pending downloads, delete request and trigger callbacks
+ removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE);
+ mCoroWaitList.pop_front();
+ }
+}
+
// virtual
void LLViewerAssetStorage::storeAssetData(
const LLTransactionID& tid,
@@ -168,7 +188,7 @@ void LLViewerAssetStorage::storeAssetData(
delete req;
if (callback)
{
- callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
+ callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LLExtStat::VFS_CORRUPT);
}
return;
}
@@ -209,7 +229,7 @@ void LLViewerAssetStorage::storeAssetData(
if (callback)
{
- callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
+ callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LLExtStat::VFS_CORRUPT);
}
return;
}
@@ -236,7 +256,7 @@ void LLViewerAssetStorage::storeAssetData(
reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
if (callback)
{
- callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
+ callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LLExtStat::NONEXISTENT_FILE);
}
}
}
@@ -247,7 +267,7 @@ void LLViewerAssetStorage::storeAssetData(
reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
if (callback)
{
- callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
+ callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);
}
}
}
@@ -333,11 +353,32 @@ void LLViewerAssetStorage::storeAssetData(
}
if (callback)
{
- callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
+ callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LLExtStat::BLOCKED_FILE);
}
}
}
+void LLViewerAssetStorage::checkForTimeouts()
+{
+ LLAssetStorage::checkForTimeouts();
+
+ // Restore requests
+ LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
+ while (mCoroWaitList.size() > 0
+ && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+ {
+ CoroWaitList &request = mCoroWaitList.front();
+
+ bool with_http = true;
+ bool is_temp = false;
+ LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp);
+
+ manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+ boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData));
+
+ mCoroWaitList.pop_front();
+ }
+}
/**
* @brief Allocate and queue an asset fetch request for the viewer
@@ -395,12 +436,20 @@ void LLViewerAssetStorage::queueRequestHttp(
// This is the same as the current UDP logic - don't re-request a duplicate.
if (!duplicate)
{
- bool with_http = true;
- bool is_temp = false;
- LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
+ // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit
+ if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+ {
+ bool with_http = true;
+ bool is_temp = false;
+ LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
- LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage","LLViewerAssetStorage::assetRequestCoro",
- boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+ LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+ boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+ }
+ else
+ {
+ mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data);
+ }
}
}
@@ -444,13 +493,18 @@ void LLViewerAssetStorage::assetRequestCoro(
mCountStarted++;
S32 result_code = LL_ERR_NOERR;
- LLExtStat ext_status = LL_EXSTAT_NONE;
+ LLExtStat ext_status = LLExtStat::NONE;
+ if (!gAssetStorage)
+ {
+ LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: asset storage no longer exists" << LL_ENDL;
+ return;
+ }
if (!gAgent.getRegion())
{
LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_NONE;
+ ext_status = LLExtStat::NONE;
removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);
return;
}
@@ -475,7 +529,7 @@ void LLViewerAssetStorage::assetRequestCoro(
{
LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_NONE;
+ ext_status = LLExtStat::NONE;
removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);
return;
}
@@ -490,7 +544,7 @@ void LLViewerAssetStorage::assetRequestCoro(
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts);
- if (LLApp::isQuitting())
+ if (LLApp::isQuitting() || !gAssetStorage)
{
// Bail out if result arrives after shutdown has been started.
return;
@@ -504,7 +558,7 @@ void LLViewerAssetStorage::assetRequestCoro(
{
LL_DEBUGS("ViewerAsset") << "request failed, status " << status.toTerseString() << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_NONE;
+ ext_status = LLExtStat::NONE;
}
else
{
@@ -530,13 +584,13 @@ void LLViewerAssetStorage::assetRequestCoro(
// TODO asset-http: handle error
LL_WARNS("ViewerAsset") << "Failure in vf.write()" << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_VFS_CORRUPT;
+ ext_status = LLExtStat::VFS_CORRUPT;
}
else if (!vf.rename(uuid, atype))
{
LL_WARNS("ViewerAsset") << "rename failed" << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_VFS_CORRUPT;
+ ext_status = LLExtStat::VFS_CORRUPT;
}
else
{
@@ -548,7 +602,7 @@ void LLViewerAssetStorage::assetRequestCoro(
// TODO asset-http: handle invalid size case
LL_WARNS("ViewerAsset") << "bad size" << LL_ENDL;
result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LL_EXSTAT_NONE;
+ ext_status = LLExtStat::NONE;
}
}
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index 50131682e7..c1a5534b81 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -43,7 +43,9 @@ public:
LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs, LLVFS *static_vfs);
- virtual void storeAssetData(
+ ~LLViewerAssetStorage();
+
+ void storeAssetData(
const LLTransactionID& tid,
LLAssetType::EType atype,
LLStoreAssetCallback callback,
@@ -52,9 +54,9 @@ public:
bool is_priority = false,
bool store_local = false,
bool user_waiting=FALSE,
- F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
-
- virtual void storeAssetData(
+ F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+ void storeAssetData(
const std::string& filename,
const LLTransactionID& tid,
LLAssetType::EType type,
@@ -63,20 +65,21 @@ public:
bool temp_file = false,
bool is_priority = false,
bool user_waiting=FALSE,
- F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
+ F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+ void checkForTimeouts() override;
protected:
- // virtual
void _queueDataRequest(const LLUUID& uuid,
LLAssetType::EType type,
- void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+ LLGetAssetCallback callback,
void *user_data,
BOOL duplicate,
- BOOL is_priority);
+ BOOL is_priority) override;
void queueRequestHttp(const LLUUID& uuid,
LLAssetType::EType type,
- void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+ LLGetAssetCallback callback,
void *user_data,
BOOL duplicate,
BOOL is_priority);
@@ -86,13 +89,40 @@ protected:
void assetRequestCoro(LLViewerAssetRequest *req,
const LLUUID uuid,
LLAssetType::EType atype,
- void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+ LLGetAssetCallback callback,
void *user_data);
std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype);
- void logAssetStorageInfo();
-
+ void logAssetStorageInfo() override;
+
+ // Asset storage works through coroutines and coroutines have limited queue capacity
+ // This class is meant to temporary store requests when fiber's queue is full
+ class CoroWaitList
+ {
+ public:
+ CoroWaitList(LLViewerAssetRequest *req,
+ const LLUUID& uuid,
+ LLAssetType::EType atype,
+ LLGetAssetCallback &callback,
+ void *user_data)
+ : mRequest(req),
+ mId(uuid),
+ mType(atype),
+ mCallback(callback),
+ mUserData(user_data)
+ {
+ }
+
+ LLViewerAssetRequest* mRequest;
+ LLUUID mId;
+ LLAssetType::EType mType;
+ LLGetAssetCallback mCallback;
+ void *mUserData;
+ };
+ typedef std::list<CoroWaitList> wait_list_t;
+ wait_list_t mCoroWaitList;
+
std::string mViewerAssetUrl;
S32 mAssetCoroCount;
S32 mCountRequests;
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index f07c14d01f..4804ef6ddc 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -87,6 +87,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_UNKNOWN, new ViewerAssetEntry(DAD_NONE));
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
+ addEntry(LLViewerAssetType::AT_SETTINGS, new ViewerAssetEntry(DAD_SETTINGS));
};
EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type)
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 97fbb8c601..bc07821ccd 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -36,7 +36,6 @@
#include "lluploaddialog.h"
#include "llpreviewscript.h"
#include "llnotificationsutil.h"
-#include "lleconomy.h"
#include "llagent.h"
#include "llfloaterreg.h"
#include "llfloatersnapshot.h"
@@ -171,22 +170,6 @@ void LLResourceUploadInfo::logPreparedUpload()
"Asset Type: " << LLAssetType::lookup(mAssetType) << LL_ENDL;
}
-S32 LLResourceUploadInfo::getEconomyUploadCost()
-{
- // Update L$ and ownership credit information
- // since it probably changed on the server
- if (getAssetType() == LLAssetType::AT_TEXTURE ||
- getAssetType() == LLAssetType::AT_SOUND ||
- getAssetType() == LLAssetType::AT_ANIMATION ||
- getAssetType() == LLAssetType::AT_MESH)
- {
- return LLGlobalEconomy::instance().getPriceUpload();
- }
-
- return 0;
-}
-
-
LLUUID LLResourceUploadInfo::finishUpload(LLSD &result)
{
if (getFolderId().isNull())
@@ -323,6 +306,43 @@ std::string LLResourceUploadInfo::getDisplayName() const
return (mName.empty()) ? mAssetId.asString() : mName;
};
+bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type)
+{
+ U32 codec;
+ return findAssetTypeAndCodecOfExtension(exten, asset_type, codec, false);
+}
+
+// static
+bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload)
+{
+ bool succ = false;
+ std::string exten_lc(exten);
+ LLStringUtil::toLower(exten_lc);
+ codec = LLImageBase::getCodecFromExtension(exten_lc);
+ if (codec != IMG_CODEC_INVALID)
+ {
+ asset_type = LLAssetType::AT_TEXTURE;
+ succ = true;
+ }
+ else if (exten_lc == "wav")
+ {
+ asset_type = LLAssetType::AT_SOUND;
+ succ = true;
+ }
+ else if (exten_lc == "anim")
+ {
+ asset_type = LLAssetType::AT_ANIMATION;
+ succ = true;
+ }
+ else if (!bulk_upload && (exten_lc == "bvh"))
+ {
+ asset_type = LLAssetType::AT_ANIMATION;
+ succ = true;
+ }
+
+ return succ;
+}
+
//=========================================================================
LLNewFileResourceUploadInfo::LLNewFileResourceUploadInfo(
std::string fileName,
@@ -360,9 +380,11 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
std::string filename = gDirUtilp->getTempFilename();
std::string exten = gDirUtilp->getExtension(getFileName());
- U32 codec = LLImageBase::getCodecFromExtension(exten);
LLAssetType::EType assetType = LLAssetType::AT_NONE;
+ U32 codec = IMG_CODEC_INVALID;
+ bool found_type = findAssetTypeAndCodecOfExtension(exten, assetType, codec);
+
std::string errorMessage;
std::string errorLabel;
@@ -379,10 +401,16 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "NoFileExtension";
error = true;
}
- else if (codec != IMG_CODEC_INVALID)
+ else if (!found_type)
+ {
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
+ }
+ else if (assetType == LLAssetType::AT_TEXTURE)
{
// It's an image file, the upload procedure is the same for all
- assetType = LLAssetType::AT_TEXTURE;
if (!LLViewerTextureList::createUploadFile(getFileName(), filename, codec))
{
errorMessage = llformat("Problem with file %s:\n\n%s\n",
@@ -391,9 +419,8 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
error = true;
}
}
- else if (exten == "wav")
+ else if (assetType == LLAssetType::AT_SOUND)
{
- assetType = LLAssetType::AT_SOUND; // tag it as audio
S32 encodeResult = 0;
LL_INFOS() << "Attempting to encode wav as an ogg file" << LL_ENDL;
@@ -423,18 +450,10 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
- else if (exten == "anim")
+ else if (assetType == LLAssetType::AT_ANIMATION)
{
- assetType = LLAssetType::AT_ANIMATION;
filename = getFileName();
}
- else
- {
- // Unknown extension
- errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
- errorLabel = "ErrorMessage";
- error = TRUE;;
- }
if (error)
{
@@ -487,7 +506,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType:
mTaskId(LLUUID::null),
mContents(buffer),
mInvnFinishFn(finish),
- mTaskFinishFn(NULL),
+ mTaskFinishFn(nullptr),
mStoredToVFS(false)
{
setItemId(itemId);
@@ -501,7 +520,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL
mTaskId(LLUUID::null),
mContents(),
mInvnFinishFn(finish),
- mTaskFinishFn(NULL),
+ mTaskFinishFn(nullptr),
mStoredToVFS(false)
{
setItemId(itemId);
@@ -534,7 +553,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemI
mTaskUpload(true),
mTaskId(taskId),
mContents(buffer),
- mInvnFinishFn(NULL),
+ mInvnFinishFn(nullptr),
mTaskFinishFn(finish),
mStoredToVFS(false)
{
@@ -739,8 +758,12 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLUploadDialog::modalUploadFinished();
return;
}
+ if (!result.has("success"))
+ {
+ result["success"] = LLSD::Boolean((ulstate == "complete") && status);
+ }
- S32 uploadPrice = result["upload_price"].asInteger();//uploadInfo->getEconomyUploadCost();
+ S32 uploadPrice = result["upload_price"].asInteger();
if (uploadPrice > 0)
{
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
index ee1806b782..d9eacf3167 100644
--- a/indra/newview/llviewerassetupload.h
+++ b/indra/newview/llviewerassetupload.h
@@ -40,7 +40,7 @@
class LLResourceUploadInfo
{
public:
- typedef boost::shared_ptr<LLResourceUploadInfo> ptr_t;
+ typedef std::shared_ptr<LLResourceUploadInfo> ptr_t;
LLResourceUploadInfo(
LLTransactionID transactId,
@@ -62,7 +62,6 @@ public:
virtual LLSD prepareUpload();
virtual LLSD generatePostBody();
virtual void logPreparedUpload();
- virtual S32 getEconomyUploadCost();
virtual LLUUID finishUpload(LLSD &result);
LLTransactionID getTransactionId() const { return mTransactionId; }
@@ -88,6 +87,9 @@ public:
LLUUID getItemId() const { return mItemId; }
LLAssetID getAssetId() const { return mAssetId; }
+ static bool findAssetTypeOfExtension(const std::string& exten, LLAssetType::EType& asset_type);
+ static bool findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload = true);
+
protected:
LLResourceUploadInfo(
std::string name,
@@ -169,8 +171,8 @@ private:
class LLBufferedAssetUploadInfo : public LLResourceUploadInfo
{
public:
- typedef boost::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f;
- typedef boost::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f;
+ typedef std::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f;
+ typedef std::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f;
LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish);
LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LLImageFormatted> image, invnUploadFinish_f finish);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 778e275727..27a87ee1a0 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -81,31 +81,6 @@ glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height
return glh::matrix4f(m);
}
-glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
-{
- GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f);
-
- return glh::matrix4f(f/aspect, 0, 0, 0,
- 0, f, 0, 0,
- 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar),
- 0, 0, -1.f, 0);
-}
-
-glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up)
-{
- LLVector3 f = center-eye;
- f.normVec();
- up.normVec();
- LLVector3 s = f % up;
- LLVector3 u = s % f;
-
- return glh::matrix4f(s[0], s[1], s[2], 0,
- u[0], u[1], u[2], 0,
- -f[0], -f[1], -f[2], 0,
- 0, 0, 0, 1);
-
-}
-
// Build time optimization, generate this once in .cpp file
template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance();
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 5901de289f..fb07a3fb2d 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -35,14 +35,6 @@
#include "lltrace.h"
class LLViewerObject;
-
-// This rotation matrix moves the default OpenGL reference frame
-// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
-const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X
- -1.f, 0.f, 0.f, 0.f, // -X becomes Y
- 0.f, 1.f, 0.f, 0.f, // Y becomes Z
- 0.f, 0.f, 0.f, 1.f };
-
const BOOL FOR_SELECTION = TRUE;
const BOOL NOT_FOR_SELECTION = FALSE;
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index a699491e1b..76dc9a6790 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -94,6 +94,7 @@ LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warning
std::string gLastRunVersion;
extern BOOL gResizeScreenTexture;
+extern BOOL gResizeShadowTexture;
extern BOOL gDebugGL;
////////////////////////////////////////////////////////////////////////////
// Listeners
@@ -186,10 +187,33 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
+ LLRenderTarget::sUseFBO = newvalue.asBoolean();
+ if (gPipeline.isInit())
+ {
+ gPipeline.updateRenderTransparentWater();
+ gPipeline.updateRenderDeferred();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
LLWorld::getInstance()->updateWaterObjects();
return true;
}
+
+static bool handleShadowsResized(const LLSD& newvalue)
+{
+ gPipeline.requestResizeShadowTexture();
+ return true;
+}
+
+static bool handleWindowResized(const LLSD& newvalue)
+{
+ gPipeline.requestResizeScreenTexture();
+ return true;
+}
+
static bool handleReleaseGLBufferChanged(const LLSD& newvalue)
{
if (gPipeline.isInit())
@@ -486,7 +510,10 @@ bool handleHighResSnapshotChanged(const LLSD& newvalue)
bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
{
- LLVoiceClient::getInstance()->updateSettings();
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->updateSettings();
+ }
return true;
}
@@ -608,15 +635,14 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _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(&handleReleaseGLBufferChanged, _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));
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index d2484b2b23..3443bb644a 100644
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -50,11 +50,9 @@ LLViewerControlListener::LLViewerControlListener()
std::ostringstream groupnames;
groupnames << "[\"group\"] is one of ";
const char* delim = "";
- for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
- cgkend(LLControlGroup::endKeys());
- cgki != cgkend; ++cgki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
- groupnames << delim << '"' << *cgki << '"';
+ groupnames << delim << '"' << key << '"';
delim = ", ";
}
groupnames << '\n';
@@ -181,11 +179,9 @@ void LLViewerControlListener::groups(LLSD const & request)
{
// No Info, we're not looking up either a group or a control name.
Response response(LLSD(), request);
- for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
- cgkend(LLControlGroup::endKeys());
- cgki != cgkend; ++cgki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
- response["groups"].append(*cgki);
+ response["groups"].append(key);
}
}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 6df849674f..066c874eb8 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -74,11 +74,11 @@
#include "llviewerregion.h"
#include "lldrawpoolwater.h"
#include "lldrawpoolbump.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llpostprocess.h"
#include "llscenemonitor.h"
+#include "llenvironment.h"
+
extern LLPointer<LLViewerTexture> gStartTexture;
extern bool gShiftFrame;
@@ -94,6 +94,7 @@ BOOL gForceRenderLandFence = FALSE;
BOOL gDisplaySwapBuffers = FALSE;
BOOL gDepthDirty = FALSE;
BOOL gResizeScreenTexture = FALSE;
+BOOL gResizeShadowTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
BOOL gShaderProfileFrame = FALSE;
@@ -130,9 +131,6 @@ void display_startup()
gPipeline.updateGL();
- // Update images?
- //gImageList.updateImages(0.01f);
-
// Written as branch to appease GCC which doesn't like different
// pointer types across ternary ops
//
@@ -153,6 +151,10 @@ void display_startup()
{
LLViewerDynamicTexture::updateAllInstances();
}
+ else
+ {
+ LL_DEBUGS("Window") << "First display_startup frame" << LL_ENDL;
+ }
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -199,10 +201,6 @@ void display_update_camera()
LLViewerCamera::getInstance()->setFar(final_far);
gViewerWindow->setup3DRender();
- // update all the sky/atmospheric/water settings
- LLWLParamManager::getInstance()->update(LLViewerCamera::getInstance());
- LLWaterParamManager::getInstance()->update(LLViewerCamera::getInstance());
-
// Update land visibility too
LLWorld::getInstance()->setLandFarClip(final_far);
}
@@ -250,6 +248,7 @@ static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update");
static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom");
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UNBIND("Texture Unbind");
static LLTrace::BlockTimerStatHandle FTM_TELEPORT_DISPLAY("Teleport Display");
+static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
@@ -258,6 +257,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gWindowResized)
{ //skip render on frames where window has been resized
+ LL_DEBUGS("Window") << "Resizing window" << LL_ENDL;
LL_RECORD_BLOCK_TIME(FTM_RESIZE_WINDOW);
gGL.flush();
glClear(GL_COLOR_BUFFER_BIT);
@@ -269,6 +269,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
return;
}
+ if (gResizeShadowTexture)
+ { //skip render on frames where window has been resized
+ gPipeline.resizeShadowTexture();
+ gResizeShadowTexture = FALSE;
+ }
+
if (LLPipeline::sRenderDeferred)
{ //hack to make sky show up in deferred snapshots
for_snapshot = FALSE;
@@ -417,6 +423,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
{
// Give up. Don't keep the UI locked forever.
+ LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
gAgent.setTeleportMessage(std::string());
}
@@ -438,6 +445,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTeleportDisplayTimer.reset();
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+ LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
gAgent.setTeleportMessage(
LLAgent::sTeleportProgressMessages["requesting"]);
@@ -462,9 +470,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTeleportArrivalTimer.reset();
gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
gViewerWindow->setProgressPercent(75.f);
+ LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
gAgent.setTeleportMessage(
LLAgent::sTeleportProgressMessages["arriving"]);
+ gAgent.sheduleTeleportIM();
gTextureList.mForceResetTextureStats = TRUE;
gAgentCamera.resetView(TRUE, TRUE);
@@ -478,6 +488,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
arrival_fraction = 1.f;
//LLFirstUse::useTeleport();
+ LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
@@ -493,6 +504,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() )
{
//LLFirstUse::useTeleport();
+ LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
+ << " exceeds teleport_local_delete " << teleport_local_delay
+ << "; setting state to TELEPORT_NONE"
+ << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
}
@@ -569,7 +584,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gDisconnected)
{
LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
render_ui();
swap();
}
@@ -634,6 +648,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
display_update_camera();
stop_glerror();
+ {
+ LL_RECORD_BLOCK_TIME(FTM_EEP_UPDATE);
+ // update all the sky/atmospheric/water settings
+ LLEnvironment::instance().update(LLViewerCamera::getInstance());
+ }
+
// *TODO: merge these two methods
{
LL_RECORD_BLOCK_TIME(FTM_HUD_UPDATE);
@@ -656,7 +676,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
S32 water_clip = 0;
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||
gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
{
@@ -699,9 +719,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
- BOOL to_texture = gPipeline.canUseVertexShaders() &&
- LLPipeline::sRenderGlow;
-
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
{
@@ -732,18 +749,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
- glh::matrix4f proj = glh_get_current_projection();
- glh::matrix4f mod = glh_get_current_modelview();
+ glh::matrix4f proj = get_current_projection();
+ glh::matrix4f mod = get_current_modelview();
glViewport(0,0,512,512);
LLVOAvatar::updateFreezeCounter() ;
- if(!LLPipeline::sMemAllocationThrottled)
- {
- LLVOAvatar::updateImpostors();
- }
+ LLVOAvatar::updateImpostors();
- glh_set_current_projection(proj);
- glh_set_current_modelview(mod);
+ set_current_projection(proj);
+ set_current_modelview(mod);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.loadMatrix(proj.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -901,38 +915,35 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// gGL.popMatrix();
//}
- LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
LLGLState::checkStates();
LLGLState::checkClientArrays();
stop_glerror();
- if (to_texture)
- {
- gGL.setColorMask(true, true);
-
- if (LLPipeline::sRenderDeferred)
- {
- gPipeline.mDeferredScreen.bindTarget();
- glClearColor(1,0,1,1);
- gPipeline.mDeferredScreen.clear();
- }
- else
- {
- gPipeline.mScreen.bindTarget();
- if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
- {
- const LLColor4 &col = LLDrawPoolWater::sWaterFogColor;
- glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
- }
- gPipeline.mScreen.clear();
- }
-
- gGL.setColorMask(true, false);
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
+ gGL.setColorMask(true, true);
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ gPipeline.mDeferredScreen.bindTarget();
+ glClearColor(1, 0, 1, 1);
+ gPipeline.mDeferredScreen.clear();
+ }
+ else
+ {
+ gPipeline.mScreen.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();
+ }
+
+ gGL.setColorMask(true, false);
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
&& !gRestoreGL)
@@ -994,39 +1005,21 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
- LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
-
- if (to_texture)
- {
- if (LLPipeline::sRenderDeferred)
- {
- gPipeline.mDeferredScreen.flush();
- if(LLRenderTarget::sUseFBO)
- {
- LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(),
- gPipeline.mDeferredScreen.getHeight(), 0, 0,
- gPipeline.mDeferredScreen.getWidth(),
- gPipeline.mDeferredScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
- }
- else
- {
- gPipeline.mScreen.flush();
- if(LLRenderTarget::sUseFBO)
- {
- LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(),
- gPipeline.mScreen.getHeight(), 0, 0,
- gPipeline.mScreen.getWidth(),
- gPipeline.mScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
- }
- }
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
- if (LLPipeline::sRenderDeferred)
- {
- gPipeline.renderDeferredLighting();
+ LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+ rt.flush();
+
+ 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);
}
LLPipeline::sUnderWaterRender = FALSE;
@@ -1039,7 +1032,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
if (!for_snapshot)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
render_ui();
swap();
}
@@ -1081,8 +1073,8 @@ void render_hud_attachments()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- glh::matrix4f current_proj = glh_get_current_projection();
- glh::matrix4f current_mod = glh_get_current_modelview();
+ glh::matrix4f current_proj = get_current_projection();
+ glh::matrix4f current_mod = get_current_modelview();
// clamp target zoom level to reasonable values
gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
@@ -1174,8 +1166,8 @@ void render_hud_attachments()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- glh_set_current_projection(current_proj);
- glh_set_current_modelview(current_mod);
+ set_current_projection(current_proj);
+ set_current_modelview(current_mod);
}
LLRect get_whole_screen_region()
@@ -1257,29 +1249,32 @@ bool setup_hud_matrices(const LLRect& screen_region)
// set up transform to keep HUD objects in front of camera
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.loadMatrix(proj.m);
- glh_set_current_projection(proj);
+ set_current_projection(proj);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(model.m);
- glh_set_current_modelview(model);
+ set_current_modelview(model);
return TRUE;
}
void render_ui(F32 zoom_factor, int subfield)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
+
LLGLState::checkStates();
- glh::matrix4f saved_view = glh_get_current_modelview();
+ glh::matrix4f saved_view = get_current_modelview();
if (!gSnapshot)
{
gGL.pushMatrix();
gGL.loadMatrix(gGLLastModelView);
- glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));
+ set_current_modelview(copy_matrix(gGLLastModelView));
}
if(LLSceneMonitor::getInstance()->needsUpdate())
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_SCENE_MON);
gGL.pushMatrix();
gViewerWindow->setup2DRender();
LLSceneMonitor::getInstance()->compare();
@@ -1287,19 +1282,12 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- {
- BOOL to_texture = gPipeline.canUseVertexShaders() &&
- LLPipeline::sRenderGlow;
-
- if (to_texture)
- {
- gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
- }
+ // Finalize scene
+ gPipeline.renderFinalize();
- LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
- render_hud_elements();
- render_hud_attachments();
- }
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
+ render_hud_elements();
+ render_hud_attachments();
LLGLSDefault gls_default;
LLGLSUIDefault gls_ui;
@@ -1313,6 +1301,7 @@ void render_ui(F32 zoom_factor, int subfield)
{
if (!gDisconnected)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
render_ui_3d();
LLGLState::checkStates();
}
@@ -1321,12 +1310,14 @@ void render_ui(F32 zoom_factor, int subfield)
render_disconnected_background();
}
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
render_ui_2d();
LLGLState::checkStates();
}
gGL.flush();
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_DEBUG_TEXT);
gViewerWindow->setup2DRender();
gViewerWindow->updateDebugText();
gViewerWindow->drawDebugText();
@@ -1337,7 +1328,7 @@ void render_ui(F32 zoom_factor, int subfield)
if (!gSnapshot)
{
- glh_set_current_modelview(saved_view);
+ set_current_modelview(saved_view);
gGL.popMatrix();
}
}
diff --git a/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h
index f6467d7f93..e8072193ea 100644
--- a/indra/newview/llviewerdisplay.h
+++ b/indra/newview/llviewerdisplay.h
@@ -40,6 +40,7 @@ extern BOOL gTeleportDisplay;
extern LLFrameTimer gTeleportDisplayTimer;
extern BOOL gForceRenderLandFence;
extern BOOL gResizeScreenTexture;
+extern BOOL gResizeShadowTexture;
extern BOOL gWindowResized;
#endif // LL_LLVIEWERDISPLAY_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7e0f449d59..5a05f89758 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -34,6 +34,7 @@
#include "llcompilequeue.h"
#include "llfasttimerview.h"
#include "llfloaterabout.h"
+#include "llfloateraddpaymentmethod.h"
#include "llfloaterauction.h"
#include "llfloaterautoreplacesettings.h"
#include "llfloateravatar.h"
@@ -53,27 +54,29 @@
#include "llfloaterbuyland.h"
#include "llfloaterbvhpreview.h"
#include "llfloatercamera.h"
+#include "llfloatercamerapresets.h"
#include "llfloaterchatvoicevolume.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
-#include "llfloaterdeleteenvpreset.h"
+#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
-#include "llfloatereditdaycycle.h"
-#include "llfloatereditsky.h"
-#include "llfloatereditwater.h"
-#include "llfloaterenvironmentsettings.h"
+#include "llfloatereditextdaycycle.h"
+#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
+#include "llfloaterfixedenvironment.h"
#include "llfloaterfonttest.h"
+#include "llfloaterforgetuser.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergridstatus.h"
#include "llfloatergroups.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterhoverheight.h"
+#include "llfloaterhowto.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
#include "llfloaterimsession.h"
@@ -90,6 +93,7 @@
#include "llfloatermemleak.h"
#include "llfloatermodelpreview.h"
#include "llfloatermyscripts.h"
+#include "llfloatermyenvironment.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaternotificationstabbed.h"
@@ -104,12 +108,14 @@
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
#include "llfloaterpreference.h"
+#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
#include "llfloaterregionrestarting.h"
#include "llfloaterreporter.h"
+#include "llfloatersavecamerapreset.h"
#include "llfloatersaveprefpreset.h"
#include "llfloatersceneloadstats.h"
#include "llfloaterscriptdebug.h"
@@ -191,6 +197,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterAboutUtil::registerFloater();
LLFloaterReg::add("block_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);
LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
+ LLFloaterReg::add("add_payment_method", "floater_add_payment_method.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAddPaymentMethod>);
LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);
LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
@@ -212,20 +219,25 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
+ 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("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>);
LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);
LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>);
- LLFloaterReg::add("env_settings", "floater_environment_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentSettings>);
- LLFloaterReg::add("env_delete_preset", "floater_delete_env_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteEnvPreset>);
- LLFloaterReg::add("env_edit_sky", "floater_edit_sky_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditSky>);
- LLFloaterReg::add("env_edit_water", "floater_edit_water_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditWater>);
- LLFloaterReg::add("env_edit_day_cycle", "floater_edit_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditDayCycle>);
+
+ LLFloaterReg::add("env_fixed_environmentent_water", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentWater>);
+ LLFloaterReg::add("env_fixed_environmentent_sky", "floater_fixedenvironment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFixedEnvironmentSky>);
+
+ LLFloaterReg::add("env_adjust_snapshot", "floater_adjust_environment.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvironmentAdjust>);
+
+ LLFloaterReg::add("env_edit_extdaycycle", "floater_edit_ext_day_cycle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEditExtDayCycle>);
+ LLFloaterReg::add("my_environments", "floater_my_environments.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyEnvironment>);
LLFloaterReg::add("event", "floater_event.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEvent>);
LLFloaterReg::add("experiences", "floater_experiences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiences>);
@@ -233,6 +245,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);
LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
+ LLFloaterReg::add("forget_username", "floater_forget_user.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterForgetUser>);
LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
@@ -295,6 +308,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
LLFloaterReg::add("prefs_graphics_advanced", "floater_preferences_graphics_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceGraphicsAdvanced>);
+ LLFloaterReg::add("prefs_view_advanced", "floater_preferences_view_advanced.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceViewAdvanced>);
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>);
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
@@ -314,6 +328,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>);
+ 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("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
@@ -348,7 +363,7 @@ void LLViewerFloaterReg::registerFloaters()
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("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
+ 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 9cb2e0336a..afa84a5afc 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -133,7 +133,8 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, true));
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));
+
bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Merchant Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp
index 3df53a4a30..d3de9d72bf 100644
--- a/indra/newview/llviewergenericmessage.cpp
+++ b/indra/newview/llviewergenericmessage.cpp
@@ -70,8 +70,6 @@ void send_generic_message(const std::string& method,
gAgent.sendReliableMessage();
}
-
-
void process_generic_message(LLMessageSystem* msg, void**)
{
LLUUID agent_id;
@@ -93,3 +91,25 @@ void process_generic_message(LLMessageSystem* msg, void**)
<< LL_ENDL;
}
}
+
+void process_large_generic_message(LLMessageSystem* msg, void**)
+{
+ LLUUID agent_id;
+ msg->getUUID("AgentData", "AgentID", agent_id);
+ if (agent_id != gAgent.getID())
+ {
+ LL_WARNS() << "GenericMessage for wrong agent" << LL_ENDL;
+ return;
+ }
+
+ std::string request;
+ LLUUID invoice;
+ LLDispatcher::sparam_t strings;
+ LLDispatcher::unpackLargeMessage(msg, request, invoice, strings);
+
+ if (!gGenericDispatcher.dispatch(request, invoice, strings))
+ {
+ LL_WARNS() << "GenericMessage " << request << " failed to dispatch"
+ << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llviewergenericmessage.h b/indra/newview/llviewergenericmessage.h
index 9d451ec0bc..170f38a485 100644
--- a/indra/newview/llviewergenericmessage.h
+++ b/indra/newview/llviewergenericmessage.h
@@ -38,6 +38,7 @@ void send_generic_message(const std::string& method,
const LLUUID& invoice = LLUUID::null);
void process_generic_message(LLMessageSystem* msg, void**);
+void process_large_generic_message(LLMessageSystem* msg, void**);
extern LLDispatcher gGenericDispatcher;
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
new file mode 100644
index 0000000000..c0eaa88f54
--- /dev/null
+++ b/indra/newview/llviewerinput.cpp
@@ -0,0 +1,1540 @@
+/**
+ * @file llviewerinput.cpp
+ * @brief LLViewerInput class implementation
+ *
+ * $LicenseInfo:firstyear=2005&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 "llviewerinput.h"
+
+#include "llappviewer.h"
+#include "llfloaterreg.h"
+#include "llmath.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llfloaterimnearbychat.h"
+#include "llfocusmgr.h"
+#include "llkeybind.h" // LLKeyData
+#include "llmorphview.h"
+#include "llmoveview.h"
+#include "lltoolfocus.h"
+#include "lltoolpie.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+#include "llvoavatarself.h"
+#include "llfloatercamera.h"
+#include "llinitparam.h"
+#include "llselectmgr.h"
+
+//
+// Constants
+//
+
+const F32 FLY_TIME = 0.5f;
+const F32 FLY_FRAMES = 4;
+
+const F32 NUDGE_TIME = 0.25f; // in seconds
+const S32 NUDGE_FRAMES = 2;
+const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
+
+const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true);
+
+struct LLKeyboardActionRegistry
+: public LLRegistrySingleton<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry>
+{
+ LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);
+};
+
+LLViewerInput gViewerInput;
+
+bool agent_jump( EKeystate s )
+{
+ static BOOL first_fly_attempt(TRUE);
+ if (KEYSTATE_UP == s)
+ {
+ first_fly_attempt = TRUE;
+ return true;
+ }
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+ if( time < FLY_TIME
+ || frame_count <= FLY_FRAMES
+ || gAgent.upGrabbed()
+ || !gSavedSettings.getBOOL("AutomaticFly"))
+ {
+ gAgent.moveUp(1);
+ }
+ else
+ {
+ gAgent.setFlying(TRUE, first_fly_attempt);
+ first_fly_attempt = FALSE;
+ gAgent.moveUp(1);
+ }
+ return true;
+}
+
+bool agent_push_down( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgent.moveUp(-1);
+ return true;
+}
+
+static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
+{
+ if (gAgent.mDoubleTapRunMode == mode &&
+ gAgent.getRunning() &&
+ !gAgent.getAlwaysRun())
+ {
+ // Turn off temporary running.
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(gAgent.getRunning());
+ }
+}
+
+static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
+{
+ if (KEYSTATE_UP == s)
+ {
+ // Note: in case shift is already released, slide left/right run
+ // will be released in agent_turn_left()/agent_turn_right()
+ agent_check_temporary_run(mode);
+ }
+ else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
+ KEYSTATE_DOWN == s &&
+ !gAgent.getRunning())
+ {
+ if (gAgent.mDoubleTapRunMode == mode &&
+ gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME)
+ {
+ // Same walk-key was pushed again quickly; this is a
+ // double-tap so engage temporary running.
+ gAgent.setRunning();
+ gAgent.sendWalkRun(gAgent.getRunning());
+ }
+
+ // Pressing any walk-key resets the double-tap timer
+ gAgent.mDoubleTapRunTimer.reset();
+ gAgent.mDoubleTapRunMode = mode;
+ }
+}
+
+static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
+{
+ agent_handle_doubletap_run(s, mode);
+ if (KEYSTATE_UP == s) return;
+
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+ if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
+ {
+ gAgent.moveAtNudge(direction);
+ }
+ else
+ {
+ gAgent.moveAt(direction);
+ }
+}
+
+bool camera_move_forward( EKeystate s );
+
+bool agent_push_forward( EKeystate s )
+{
+ if(gAgent.isMovementLocked()) return true;
+
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_move_forward(s);
+ }
+ else
+ {
+ agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
+ }
+ return true;
+}
+
+bool camera_move_backward( EKeystate s );
+
+bool agent_push_backward( EKeystate s )
+{
+ if(gAgent.isMovementLocked()) return true;
+
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_move_backward(s);
+ }
+ else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook"))
+ {
+ gAgentCamera.changeCameraToThirdPerson();
+ }
+ else
+ {
+ agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
+ }
+ return true;
+}
+
+static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
+{
+ agent_handle_doubletap_run(s, mode);
+ if( KEYSTATE_UP == s ) return;
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+ if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
+ {
+ gAgent.moveLeftNudge(direction);
+ }
+ else
+ {
+ gAgent.moveLeft(direction);
+ }
+}
+
+
+bool agent_slide_left( EKeystate s )
+{
+ if(gAgent.isMovementLocked()) return true;
+ agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT);
+ return true;
+}
+
+
+bool agent_slide_right( EKeystate s )
+{
+ if(gAgent.isMovementLocked()) return true;
+ agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
+ return true;
+}
+
+bool camera_spin_around_cw( EKeystate s );
+
+bool agent_turn_left(EKeystate s)
+{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_spin_around_cw(s);
+ return true;
+ }
+
+ if(gAgent.isMovementLocked()) return false;
+
+ if (LLToolCamera::getInstance()->mouseSteerMode())
+ {
+ agent_slide_left(s);
+ }
+ else
+ {
+ if (KEYSTATE_UP == s)
+ {
+ // Check temporary running. In case user released 'left' key with shift already released.
+ agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
+ return true;
+ }
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
+ }
+ return true;
+}
+
+bool camera_spin_around_ccw( EKeystate s );
+
+bool agent_turn_right( EKeystate s )
+{
+ //in free camera control mode we need to intercept keyboard events for avatar movements
+ if (LLFloaterCamera::inFreeCameraMode())
+ {
+ camera_spin_around_ccw(s);
+ return true;
+ }
+
+ if(gAgent.isMovementLocked()) return false;
+
+ if (LLToolCamera::getInstance()->mouseSteerMode())
+ {
+ agent_slide_right(s);
+ }
+ else
+ {
+ if (KEYSTATE_UP == s)
+ {
+ // Check temporary running. In case user released 'right' key with shift already released.
+ agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
+ return true;
+ }
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
+ }
+ return true;
+}
+
+bool agent_look_up( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgent.movePitch(-1);
+ //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
+ return true;
+}
+
+
+bool agent_look_down( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgent.movePitch(1);
+ //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
+ return true;
+}
+
+bool agent_toggle_fly( EKeystate s )
+{
+ // Only catch the edge
+ if (KEYSTATE_DOWN == s )
+ {
+ LLAgent::toggleFlying();
+ }
+ return true;
+}
+
+F32 get_orbit_rate()
+{
+ F32 time = gKeyboard->getCurKeyElapsedTime();
+ if( time < NUDGE_TIME )
+ {
+ F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
+ //LL_INFOS() << rate << LL_ENDL;
+ return rate;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+bool camera_spin_around_ccw( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+ return true;
+}
+
+
+bool camera_spin_around_cw( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_spin_around_ccw_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true;
+ if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+ {
+ //send keystrokes, but do not change camera
+ agent_turn_right(s);
+ }
+ else
+ {
+ //change camera but do not send keystrokes
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+
+bool camera_spin_around_cw_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true;
+ if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+ {
+ //send keystrokes, but do not change camera
+ agent_turn_left(s);
+ }
+ else
+ {
+ //change camera but do not send keystrokes
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+
+bool camera_spin_over( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+ return true;
+}
+
+
+bool camera_spin_under( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_spin_over_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled())
+ {
+ //send keystrokes, but do not change camera
+ agent_jump(s);
+ }
+ else
+ {
+ //change camera but do not send keystrokes
+ gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+
+bool camera_spin_under_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled())
+ {
+ //send keystrokes, but do not change camera
+ agent_push_down(s);
+ }
+ else
+ {
+ //change camera but do not send keystrokes
+ gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+bool camera_move_forward( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitInKey( get_orbit_rate() );
+ return true;
+}
+
+
+bool camera_move_backward( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_move_forward_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true;
+ if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
+ {
+ agent_push_forward(s);
+ }
+ else
+ {
+ gAgentCamera.setOrbitInKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+bool camera_move_backward_sitting( EKeystate s )
+{
+ if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true;
+
+ if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
+ {
+ agent_push_backward(s);
+ }
+ else
+ {
+ gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+ }
+ return true;
+}
+
+bool camera_pan_up( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanUpKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_pan_down( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanDownKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_pan_left( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanLeftKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_pan_right( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanRightKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_pan_in( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanInKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_pan_out( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setPanOutKey( get_orbit_rate() );
+ return true;
+}
+
+bool camera_move_forward_fast( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitInKey(2.5f);
+ return true;
+}
+
+bool camera_move_backward_fast( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gAgentCamera.unlockView();
+ gAgentCamera.setOrbitOutKey(2.5f);
+ return true;
+}
+
+
+bool edit_avatar_spin_ccw( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+ //gMorphView->orbitLeft( get_orbit_rate() );
+ return true;
+}
+
+
+bool edit_avatar_spin_cw( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+ //gMorphView->orbitRight( get_orbit_rate() );
+ return true;
+}
+
+bool edit_avatar_spin_over( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+ //gMorphView->orbitUp( get_orbit_rate() );
+ return true;
+}
+
+
+bool edit_avatar_spin_under( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+ //gMorphView->orbitDown( get_orbit_rate() );
+ return true;
+}
+
+bool edit_avatar_move_forward( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitInKey( get_orbit_rate() );
+ //gMorphView->orbitIn();
+ return true;
+}
+
+
+bool edit_avatar_move_backward( EKeystate s )
+{
+ if( KEYSTATE_UP == s ) return true;
+ gMorphView->setCameraDrivenByKeys( TRUE );
+ gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+ //gMorphView->orbitOut();
+ return true;
+}
+
+bool stop_moving( EKeystate s )
+{
+ //it's supposed that 'stop moving' key will be held down for some time
+ if( KEYSTATE_UP == s ) return true;
+ // stop agent
+ gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+ // cancel autopilot
+ gAgent.stopAutoPilot();
+ return true;
+}
+
+bool start_chat( EKeystate s )
+{
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return true; // can't talk, gotta go, kthxbye!
+ }
+ if (KEYSTATE_DOWN != s) return true;
+
+ // start chat
+ LLFloaterIMNearbyChat::startChat(NULL);
+ return true;
+}
+
+bool start_gesture( EKeystate s )
+{
+ LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+ if (KEYSTATE_UP == s &&
+ ! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
+ {
+ if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
+ {
+ // No existing chat in chat editor, insert '/'
+ LLFloaterIMNearbyChat::startChat("/");
+ }
+ else
+ {
+ // Don't overwrite existing text in chat editor
+ LLFloaterIMNearbyChat::startChat(NULL);
+ }
+ }
+ return true;
+}
+
+bool run_forward(EKeystate s)
+{
+ if (KEYSTATE_UP != s)
+ {
+ if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD)
+ {
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_FORWARD;
+ }
+ if (!gAgent.getRunning())
+ {
+ gAgent.setRunning();
+ gAgent.sendWalkRun(true);
+ }
+ }
+ else if(KEYSTATE_UP == s)
+ {
+ if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_FORWARD)
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(false);
+ }
+ agent_push_forward(s);
+ return true;
+}
+
+bool run_backward(EKeystate s)
+{
+ if (KEYSTATE_UP != s)
+ {
+ if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD)
+ {
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_BACKWARD;
+ }
+ if (!gAgent.getRunning())
+ {
+ gAgent.setRunning();
+ gAgent.sendWalkRun(true);
+ }
+ }
+ else if (KEYSTATE_UP == s)
+ {
+ if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_BACKWARD)
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(false);
+ }
+ agent_push_backward(s);
+ return true;
+}
+
+bool run_left(EKeystate s)
+{
+ if (KEYSTATE_UP != s)
+ {
+ if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT)
+ {
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDELEFT;
+ }
+ if (!gAgent.getRunning())
+ {
+ gAgent.setRunning();
+ gAgent.sendWalkRun(true);
+ }
+ }
+ else if (KEYSTATE_UP == s)
+ {
+ if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDELEFT)
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(false);
+ }
+ agent_slide_left(s);
+ return true;
+}
+
+bool run_right(EKeystate s)
+{
+ if (KEYSTATE_UP != s)
+ {
+ if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT)
+ {
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDERIGHT;
+ }
+ if (!gAgent.getRunning())
+ {
+ gAgent.setRunning();
+ gAgent.sendWalkRun(true);
+ }
+ }
+ else if (KEYSTATE_UP == s)
+ {
+ if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDERIGHT)
+ gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+ gAgent.clearRunning();
+ gAgent.sendWalkRun(false);
+ }
+ agent_slide_right(s);
+ return true;
+}
+
+bool toggle_run(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ bool run = gAgent.getAlwaysRun();
+ if (run)
+ {
+ gAgent.clearAlwaysRun();
+ gAgent.clearRunning();
+ }
+ else
+ {
+ gAgent.setAlwaysRun();
+ gAgent.setRunning();
+ }
+ gAgent.sendWalkRun(!run);
+ return true;
+}
+
+bool toggle_sit(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ if (gAgent.isSitting())
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ gAgent.sitDown();
+ }
+ return true;
+}
+
+bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar
+{
+ if (KEYSTATE_DOWN != s) return true;
+ bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying();
+ LLViewerMedia::getInstance()->setAllMediaPaused(pause);
+ return true;
+}
+
+bool toggle_enable_media(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying() || LLViewerMedia::getInstance()->isAnyMediaShowing();
+ LLViewerMedia::getInstance()->setAllMediaEnabled(!pause);
+ return true;
+}
+
+bool walk_to(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ return LLToolPie::getInstance()->walkToClickedLocation();
+}
+
+bool teleport_to(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ return LLToolPie::getInstance()->teleportToClickedLocation();
+}
+
+bool toggle_voice(EKeystate s)
+{
+ if (KEYSTATE_DOWN != s) return true;
+ if (!LLAgent::isActionAllowed("speak")) return false;
+ LLVoiceClient::getInstance()->toggleUserPTTState();
+ return true;
+}
+
+bool voice_follow_key(EKeystate s)
+{
+ if (KEYSTATE_DOWN == s)
+ {
+ if (!LLAgent::isActionAllowed("speak")) return false;
+ LLVoiceClient::getInstance()->setUserPTTState(true);
+ return true;
+ }
+ else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState())
+ {
+ LLVoiceClient::getInstance()->setUserPTTState(false);
+ return true;
+ }
+ return false;
+}
+
+bool agen_control_lbutton_handle(EKeystate s)
+{
+ switch (s)
+ {
+ case KEYSTATE_DOWN:
+ gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
+ break;
+ case KEYSTATE_UP:
+ gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION);
+REGISTER_KEYBOARD_ACTION("jump", agent_jump);
+REGISTER_KEYBOARD_ACTION("push_down", agent_push_down);
+REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward);
+REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward);
+REGISTER_KEYBOARD_ACTION("look_up", agent_look_up);
+REGISTER_KEYBOARD_ACTION("look_down", agent_look_down);
+REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly);
+REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left);
+REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right);
+REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left);
+REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw);
+REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over);
+REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under);
+REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting);
+REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting);
+REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward);
+REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward);
+REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting);
+REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting);
+REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up);
+REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down);
+REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left);
+REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right);
+REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in);
+REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out);
+REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast);
+REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward);
+REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving);
+REGISTER_KEYBOARD_ACTION("start_chat", start_chat);
+REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture);
+REGISTER_KEYBOARD_ACTION("run_forward", run_forward);
+REGISTER_KEYBOARD_ACTION("run_backward", run_backward);
+REGISTER_KEYBOARD_ACTION("run_left", run_left);
+REGISTER_KEYBOARD_ACTION("run_right", run_right);
+REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run);
+REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit);
+REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media);
+REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media);
+REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);
+REGISTER_KEYBOARD_ACTION("walk_to", walk_to);
+REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice);
+REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key);
+#undef REGISTER_KEYBOARD_ACTION
+
+LLViewerInput::LLViewerInput()
+{
+ resetBindings();
+
+ for (S32 i = 0; i < KEY_COUNT; i++)
+ {
+ mKeyHandledByUI[i] = FALSE;
+ }
+ for (S32 i = 0; i < CLICK_COUNT; i++)
+ {
+ mMouseLevel[i] = MOUSE_STATE_SILENT;
+ }
+ // we want the UI to never see these keys so that they can always control the avatar/camera
+ for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++)
+ {
+ mKeysSkippedByUI.insert(k);
+ }
+}
+
+// static
+BOOL LLViewerInput::modeFromString(const std::string& string, S32 *mode)
+{
+ if (string == "FIRST_PERSON")
+ {
+ *mode = MODE_FIRST_PERSON;
+ return TRUE;
+ }
+ else if (string == "THIRD_PERSON")
+ {
+ *mode = MODE_THIRD_PERSON;
+ return TRUE;
+ }
+ else if (string == "EDIT_AVATAR")
+ {
+ *mode = MODE_EDIT_AVATAR;
+ return TRUE;
+ }
+ else if (string == "SITTING")
+ {
+ *mode = MODE_SITTING;
+ return TRUE;
+ }
+ else
+ {
+ *mode = MODE_THIRD_PERSON;
+ return FALSE;
+ }
+}
+
+// static
+BOOL LLViewerInput::mouseFromString(const std::string& string, EMouseClickType *mode)
+{
+ if (string == "LMB")
+ {
+ *mode = CLICK_LEFT;
+ return TRUE;
+ }
+ else if (string == "Double LMB")
+ {
+ *mode = CLICK_DOUBLELEFT;
+ return TRUE;
+ }
+ else if (string == "MMB")
+ {
+ *mode = CLICK_MIDDLE;
+ return TRUE;
+ }
+ else if (string == "MB4")
+ {
+ *mode = CLICK_BUTTON4;
+ return TRUE;
+ }
+ else if (string == "MB5")
+ {
+ *mode = CLICK_BUTTON5;
+ return TRUE;
+ }
+ else
+ {
+ *mode = CLICK_NONE;
+ return FALSE;
+ }
+}
+
+BOOL LLViewerInput::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated)
+{
+ // check for re-map
+ EKeyboardMode mode = gViewerInput.getMode();
+ U32 keyidx = (translated_mask<<16) | translated_key;
+ key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx);
+ if (iter != mRemapKeys[mode].end())
+ {
+ translated_key = (iter->second) & 0xff;
+ translated_mask = (iter->second)>>16;
+ }
+
+ // No repeats of F-keys
+ BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12);
+ if (!repeatable_key && repeated)
+ {
+ return FALSE;
+ }
+
+ LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL;
+ // skip skipped keys
+ if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end())
+ {
+ mKeyHandledByUI[translated_key] = FALSE;
+ LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL;
+ }
+ else
+ {
+ // it is sufficient to set this value once per call to handlekey
+ // without clearing it, as it is only used in the subsequent call to scanKey
+ mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
+ // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
+ // NOT whether some UI shortcut wishes to handle the keypress
+
+ }
+ return mKeyHandledByUI[translated_key];
+}
+
+BOOL LLViewerInput::handleKeyUp(KEY translated_key, MASK translated_mask)
+{
+ return gViewerWindow->handleKeyUp(translated_key, translated_mask);
+}
+
+BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
+{
+ S32 index;
+ typedef boost::function<bool(EKeystate)> function_t;
+ function_t function = NULL;
+ std::string name;
+
+ // Allow remapping of F2-F12
+ if (function_name[0] == 'F')
+ {
+ int c1 = function_name[1] - '0';
+ int c2 = function_name[2] ? function_name[2] - '0' : -1;
+ if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9)
+ {
+ int idx = c1;
+ if (c2 >= 0)
+ idx = idx*10 + c2;
+ if (idx >=2 && idx <= 12)
+ {
+ U32 keyidx = ((mask<<16)|key);
+ (mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1)));
+ return TRUE;
+ }
+ }
+ }
+
+ // Not remapped, look for a function
+
+ function_t* result = LLKeyboardActionRegistry::getValue(function_name);
+ if (result)
+ {
+ function = *result;
+ }
+
+ if (!function)
+ {
+ LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
+ return FALSE;
+ }
+
+ // check for duplicate first and overwrite
+ S32 size = mKeyBindings[mode].size();
+ for (index = 0; index < size; index++)
+ {
+ if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask)
+ break;
+ }
+
+ if (mode >= MODE_COUNT)
+ {
+ LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
+ return FALSE;
+ }
+
+ LLKeyboardBinding bind;
+ bind.mKey = key;
+ bind.mMask = mask;
+ bind.mFunction = function;
+
+ mKeyBindings[mode].push_back(bind);
+
+ return TRUE;
+}
+
+BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name)
+{
+ S32 index;
+ typedef boost::function<bool(EKeystate)> function_t;
+ function_t function = NULL;
+
+ function_t* result = LLKeyboardActionRegistry::getValue(function_name);
+ if (result)
+ {
+ function = *result;
+ }
+
+ if (!function)
+ {
+ LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
+ return FALSE;
+ }
+
+ // check for duplicate first and overwrite
+ S32 size = mMouseBindings[mode].size();
+ for (index = 0; index < size; index++)
+ {
+ if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask)
+ break;
+ }
+
+ if (mode >= MODE_COUNT)
+ {
+ LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
+ return FALSE;
+ }
+
+ LLMouseBinding bind;
+ bind.mMouse = mouse;
+ bind.mMask = mask;
+ bind.mFunction = function;
+
+ mMouseBindings[mode].push_back(bind);
+
+ return TRUE;
+}
+
+LLViewerInput::KeyBinding::KeyBinding()
+: key("key"),
+ mouse("mouse"),
+ mask("mask"),
+ command("command")
+{}
+
+LLViewerInput::KeyMode::KeyMode()
+: bindings("binding")
+{}
+
+LLViewerInput::Keys::Keys()
+: first_person("first_person"),
+ third_person("third_person"),
+ sitting("sitting"),
+ edit_avatar("edit_avatar")
+{}
+
+void LLViewerInput::resetBindings()
+{
+ for (S32 i = 0; i < MODE_COUNT; i++)
+ {
+ mKeyBindings[i].clear();
+ mMouseBindings[i].clear();
+ }
+}
+
+S32 LLViewerInput::loadBindingsXML(const std::string& filename)
+{
+ resetBindings();
+
+ S32 binding_count = 0;
+ Keys keys;
+ LLSimpleXUIParser parser;
+
+ if (parser.readXUI(filename, keys)
+ && keys.validateBlock())
+ {
+ binding_count += loadBindingMode(keys.first_person, MODE_FIRST_PERSON);
+ binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON);
+ binding_count += loadBindingMode(keys.sitting, MODE_SITTING);
+ binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR);
+ }
+ return binding_count;
+}
+
+S32 count_masks(const MASK &mask)
+{
+ S32 res = 0;
+ if (mask & MASK_CONTROL)
+ {
+ res++;
+ }
+ if (mask & MASK_SHIFT)
+ {
+ res++;
+ }
+ if (mask & MASK_ALT)
+ {
+ res++;
+ }
+ return res;
+}
+
+bool compare_key_by_mask(LLKeyboardBinding i1, LLKeyboardBinding i2)
+{
+ return (count_masks(i1.mMask) > count_masks(i2.mMask));
+}
+
+bool compare_mouse_by_mask(LLMouseBinding i1, LLMouseBinding i2)
+{
+ return (count_masks(i1.mMask) > count_masks(i2.mMask));
+}
+
+S32 LLViewerInput::loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode)
+{
+ S32 binding_count = 0;
+ for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(),
+ end_it = keymode.bindings.end();
+ it != end_it;
+ ++it)
+ {
+ bool processed = false;
+ std::string key_str = it->key.getValue();
+ if (!key_str.empty() && key_str != "NONE")
+ {
+ KEY key;
+ LLKeyboard::keyFromString(key_str, &key);
+ if (key != KEY_NONE)
+ {
+ MASK mask;
+ LLKeyboard::maskFromString(it->mask, &mask);
+ bindKey(mode, key, mask, it->command);
+ processed = true;
+ }
+ else
+ {
+ LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL;
+ }
+ }
+ if (!processed && it->mouse.isProvided() && !it->mouse.getValue().empty())
+ {
+ EMouseClickType mouse;
+ mouseFromString(it->mouse.getValue(), &mouse);
+ if (mouse != CLICK_NONE)
+ {
+ MASK mask;
+ LLKeyboard::maskFromString(it->mask, &mask);
+ bindMouse(mode, mouse, mask, it->command);
+ processed = true;
+ }
+ else
+ {
+ LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL;
+ }
+ }
+ if (processed)
+ {
+ // total
+ binding_count++;
+ }
+ }
+
+ // sort lists by mask (so that Shift+W is executed before W, if both are assigned, but if Shift+W is not assigned W should be executed)
+ std::sort(mKeyBindings[mode].begin(), mKeyBindings[mode].end(), compare_key_by_mask);
+ std::sort(mMouseBindings[mode].begin(), mMouseBindings[mode].end(), compare_mouse_by_mask);
+
+ return binding_count;
+}
+
+EKeyboardMode LLViewerInput::getMode() const
+{
+ if ( gAgentCamera.cameraMouselook() )
+ {
+ return MODE_FIRST_PERSON;
+ }
+ else if ( gMorphView && gMorphView->getVisible())
+ {
+ return MODE_EDIT_AVATAR;
+ }
+ else if (isAgentAvatarValid() && gAgentAvatarp->isSitting())
+ {
+ return MODE_SITTING;
+ }
+ else
+ {
+ return MODE_THIRD_PERSON;
+ }
+}
+
+bool LLViewerInput::scanKey(const std::vector<LLKeyboardBinding> &binding,
+ S32 binding_count,
+ KEY key,
+ MASK mask,
+ BOOL key_down,
+ BOOL key_up,
+ BOOL key_level,
+ bool repeat) const
+{
+ for (S32 i = 0; i < binding_count; i++)
+ {
+ if (binding[i].mKey == key)
+ {
+ if ((binding[i].mMask & mask) == binding[i].mMask)
+ {
+ bool res = false;
+ if (key_down && !repeat)
+ {
+ // ...key went down this frame, call function
+ res = binding[i].mFunction( KEYSTATE_DOWN );
+ return true;
+ }
+ else if (key_up)
+ {
+ // ...key went down this frame, call function
+ res = binding[i].mFunction( KEYSTATE_UP );
+ }
+ else if (key_level)
+ {
+ // ...key held down from previous frame
+ // Not windows, just call the function.
+ res = binding[i].mFunction( KEYSTATE_LEVEL );
+ }//if
+ // Key+Mask combinations are supposed to be unique, so we won't find anything else
+ return res;
+ }//if
+ }//if
+ }//for
+ return false;
+}
+
+// Called from scanKeyboard.
+bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const
+{
+ if (LLApp::isExiting())
+ {
+ return false;
+ }
+
+ S32 mode = getMode();
+ // Consider keyboard scanning as NOT mouse event. JC
+ MASK mask = gKeyboard->currentMask(FALSE);
+
+ if (mKeyHandledByUI[key])
+ {
+ return false;
+ }
+
+ // don't process key down on repeated keys
+ BOOL repeat = gKeyboard->getKeyRepeated(key);
+
+ bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat);
+
+ if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))
+ {
+ if (key_down && !repeat)
+ {
+ res = agen_control_lbutton_handle(KEYSTATE_DOWN);
+ }
+ if (key_up)
+ {
+ res = agen_control_lbutton_handle(KEYSTATE_UP);
+ }
+ }
+ return res;
+}
+
+BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
+{
+ BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down);
+
+ if (clicktype != CLICK_NONE)
+ {
+ // Special case
+ // If UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set
+ // handle !down as if we are handling doubleclick
+
+ bool double_click_sp = (clicktype == CLICK_LEFT
+ && (mMouseLevel[CLICK_DOUBLELEFT] != MOUSE_STATE_SILENT)
+ && mMouseLevel[CLICK_LEFT] == MOUSE_STATE_SILENT);
+ if (double_click_sp && !down)
+ {
+ // Process doubleclick instead
+ clicktype = CLICK_DOUBLELEFT;
+ }
+
+
+ if (double_click_sp && down)
+ {
+ // Consume click.
+ // Due to handling, double click that is not handled will be immediately followed by LMB click
+ }
+ // If UI handled 'down', it should handle 'up' as well
+ // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI
+ else if (handled)
+ {
+ // UI handled new 'down' so iterupt whatever state we were in.
+ if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT)
+ {
+ if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+ {
+ mMouseLevel[clicktype] = MOUSE_STATE_CLICK;
+ }
+ else
+ {
+ mMouseLevel[clicktype] = MOUSE_STATE_UP;
+ }
+ }
+ }
+ else if (down)
+ {
+ if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+ {
+ // this is repeated hit (mouse does not repeat event until release)
+ // for now treat rapid clicking like mouse being held
+ mMouseLevel[clicktype] = MOUSE_STATE_LEVEL;
+ }
+ else
+ {
+ mMouseLevel[clicktype] = MOUSE_STATE_DOWN;
+ }
+ }
+ else if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT)
+ {
+ // Released mouse key
+ if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+ {
+ mMouseLevel[clicktype] = MOUSE_STATE_CLICK;
+ }
+ else
+ {
+ mMouseLevel[clicktype] = MOUSE_STATE_UP;
+ }
+ }
+ }
+
+ return handled;
+}
+
+bool LLViewerInput::scanMouse(const std::vector<LLMouseBinding> &binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const
+{
+ for (S32 i = 0; i < binding_count; i++)
+ {
+ if (binding[i].mMouse == mouse && (binding[i].mMask & mask) == binding[i].mMask)
+ {
+ bool res = false;
+ switch (state)
+ {
+ case MOUSE_STATE_DOWN:
+ res = binding[i].mFunction(KEYSTATE_DOWN);
+ break;
+ case MOUSE_STATE_CLICK:
+ // Button went down and up in scope of single frame
+ // might not work best with some functions,
+ // but some function need specific states specifically
+ res = binding[i].mFunction(KEYSTATE_DOWN);
+ res |= binding[i].mFunction(KEYSTATE_UP);
+ break;
+ case MOUSE_STATE_LEVEL:
+ res = binding[i].mFunction(KEYSTATE_LEVEL);
+ break;
+ case MOUSE_STATE_UP:
+ res = binding[i].mFunction(KEYSTATE_UP);
+ break;
+ default:
+ break;
+ }
+ // Key+Mask combinations are supposed to be unique, no need to continue
+ return res;
+ }
+ }
+ return false;
+}
+
+// todo: this recods key, scanMouse() triggers functions with EKeystate
+bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const
+{
+ bool res = false;
+ S32 mode = getMode();
+ MASK mask = gKeyboard->currentMask(TRUE);
+ res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state);
+ // no user defined actions found or those actions can't handle the key/button, handle control if nessesary
+ if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask))
+ {
+ switch (state)
+ {
+ case MOUSE_STATE_DOWN:
+ agen_control_lbutton_handle(KEYSTATE_DOWN);
+ res = true;
+ break;
+ case MOUSE_STATE_CLICK:
+ // might not work best with some functions,
+ // but some function need specific states too specifically
+ agen_control_lbutton_handle(KEYSTATE_DOWN);
+ agen_control_lbutton_handle(KEYSTATE_UP);
+ res = true;
+ break;
+ case MOUSE_STATE_UP:
+ agen_control_lbutton_handle(KEYSTATE_UP);
+ res = true;
+ break;
+ default:
+ break;
+ }
+ }
+ return res;
+}
+
+void LLViewerInput::scanMouse()
+{
+ for (S32 i = 0; i < CLICK_COUNT; i++)
+ {
+ if (mMouseLevel[i] != MOUSE_STATE_SILENT)
+ {
+ scanMouse((EMouseClickType)i, mMouseLevel[i]);
+ if (mMouseLevel[i] == MOUSE_STATE_DOWN)
+ {
+ // mouse doesn't support 'continued' state, so after handling, switch to LEVEL
+ mMouseLevel[i] = MOUSE_STATE_LEVEL;
+ }
+ else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK)
+ {
+ mMouseLevel[i] = MOUSE_STATE_SILENT;
+ }
+ }
+ }
+}
+
+bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode)
+{
+ S32 size = mMouseBindings[mode].size();
+ for (S32 index = 0; index < size; index++)
+ {
+ if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask)
+ return true;
+ }
+ return false;
+}
diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h
new file mode 100644
index 0000000000..281a209896
--- /dev/null
+++ b/indra/newview/llviewerinput.h
@@ -0,0 +1,179 @@
+/**
+ * @file llviewerinput.h
+ * @brief LLViewerInput class header file
+ *
+ * $LicenseInfo:firstyear=2005&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_LLVIEWERINPUT_H
+#define LL_LLVIEWERINPUT_H
+
+#include "llkeyboard.h" // For EKeystate
+#include "llinitparam.h"
+
+const S32 MAX_KEY_BINDINGS = 128; // was 60
+
+class LLNamedFunction
+{
+public:
+ LLNamedFunction() : mFunction(NULL) { };
+ ~LLNamedFunction() { };
+
+ std::string mName;
+ LLKeyFunc mFunction;
+};
+
+class LLKeyboardBinding
+{
+public:
+ KEY mKey;
+ MASK mMask;
+
+ LLKeyFunc mFunction;
+};
+
+class LLMouseBinding
+{
+public:
+ EMouseClickType mMouse;
+ MASK mMask;
+
+ LLKeyFunc mFunction;
+};
+
+
+typedef enum e_keyboard_mode
+{
+ MODE_FIRST_PERSON,
+ MODE_THIRD_PERSON,
+ MODE_EDIT_AVATAR,
+ MODE_SITTING,
+ MODE_COUNT
+} EKeyboardMode;
+
+class LLWindow;
+
+void bind_keyboard_functions();
+
+class LLViewerInput
+{
+public:
+ struct KeyBinding : public LLInitParam::Block<KeyBinding>
+ {
+ Mandatory<std::string> key,
+ mask,
+ command;
+ Optional<std::string> mouse; // Note, not mandatory for the sake of backward campatibility with keys.xml
+
+ KeyBinding();
+ };
+
+ struct KeyMode : public LLInitParam::Block<KeyMode>
+ {
+ Multiple<KeyBinding> bindings;
+
+ KeyMode();
+ };
+
+ struct Keys : public LLInitParam::Block<Keys>
+ {
+ Optional<KeyMode> first_person,
+ third_person,
+ sitting,
+ edit_avatar;
+
+ Keys();
+ };
+
+ LLViewerInput();
+
+ BOOL handleKey(KEY key, MASK mask, BOOL repeated);
+ BOOL handleKeyUp(KEY key, MASK mask);
+
+ S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error
+ EKeyboardMode getMode() const;
+
+ static BOOL modeFromString(const std::string& string, S32 *mode); // False on failure
+ static BOOL mouseFromString(const std::string& string, EMouseClickType *mode);// False on failure
+
+ bool scanKey(KEY key,
+ BOOL key_down,
+ BOOL key_up,
+ BOOL key_level) const;
+
+ // handleMouse() records state, scanMouse() goes through states, scanMouse(click) processes individual saved states after UI is done with them
+ BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
+ void scanMouse();
+
+ bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON);
+
+private:
+ bool scanKey(const std::vector<LLKeyboardBinding> &binding,
+ S32 binding_count,
+ KEY key,
+ MASK mask,
+ BOOL key_down,
+ BOOL key_up,
+ BOOL key_level,
+ bool repeat) const;
+
+ enum EMouseState
+ {
+ MOUSE_STATE_DOWN, // key down this frame
+ MOUSE_STATE_CLICK, // key went up and down in scope of same frame
+ MOUSE_STATE_LEVEL, // clicked again fast, or never released
+ MOUSE_STATE_UP, // went up this frame
+ MOUSE_STATE_SILENT // notified about 'up', do not notify again
+ };
+ bool scanMouse(EMouseClickType click, EMouseState state) const;
+ bool scanMouse(const std::vector<LLMouseBinding> &binding,
+ S32 binding_count,
+ EMouseClickType mouse,
+ MASK mask,
+ EMouseState state) const;
+
+ S32 loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode);
+ BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name);
+ BOOL bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name);
+ void resetBindings();
+
+ // Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
+
+ // TODO: at some point it is better to remake this, especially keyaboard part
+ // would be much better to send to functions actual state of the button than
+ // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)
+ std::vector<LLKeyboardBinding> mKeyBindings[MODE_COUNT];
+ std::vector<LLMouseBinding> mMouseBindings[MODE_COUNT];
+
+ typedef std::map<U32, U32> key_remap_t;
+ key_remap_t mRemapKeys[MODE_COUNT];
+ std::set<KEY> mKeysSkippedByUI;
+ BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI
+
+ // This is indentical to what llkeyboard does (mKeyRepeated, mKeyLevel, mKeyDown e t c),
+ // just instead of remembering individually as bools, we record state as enum
+ EMouseState mMouseLevel[CLICK_COUNT]; // records of key state
+};
+
+extern LLViewerInput gViewerInput;
+
+#endif // LL_LLVIEWERINPUT_H
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 9d7da115ac..bbed741a33 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -70,6 +70,7 @@
#include "llfloaterperms.h"
#include "llclipboard.h"
#include "llhttpretrypolicy.h"
+#include "llsettingsvo.h"
// do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
@@ -80,6 +81,9 @@ static const char * const LOG_INV("Inventory");
static const char * const LOG_LOCAL("InventoryLocalize");
static const char * const LOG_NOTECARD("copy_inventory_from_notecard");
+static const std::string INV_OWNER_ID("owner_id");
+static const std::string INV_VERSION("version");
+
#if 1
// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model.
// temp code in transition
@@ -518,14 +522,6 @@ void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const
}
// virtual
-BOOL LLViewerInventoryItem::importFile(LLFILE* fp)
-{
- BOOL rv = LLInventoryItem::importFile(fp);
- mIsComplete = TRUE;
- return rv;
-}
-
-// virtual
BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
{
BOOL rv = LLInventoryItem::importLegacyStream(input_stream);
@@ -533,32 +529,6 @@ BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
return rv;
}
-bool LLViewerInventoryItem::importFileLocal(LLFILE* fp)
-{
- // TODO: convert all functions that return BOOL to return bool
- bool rv = (LLInventoryItem::importFile(fp) ? true : false);
- mIsComplete = false;
- return rv;
-}
-
-bool LLViewerInventoryItem::exportFileLocal(LLFILE* fp) const
-{
- std::string uuid_str;
- fprintf(fp, "\tinv_item\t0\n\t{\n");
- mUUID.toString(uuid_str);
- fprintf(fp, "\t\titem_id\t%s\n", uuid_str.c_str());
- mParentUUID.toString(uuid_str);
- fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
- mPermissions.exportFile(fp);
- fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
- const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
- if(!inv_type_str.empty()) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str.c_str());
- fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
- fprintf(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
- fprintf(fp,"\t}\n");
- return true;
-}
-
void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
{
LLMessageSystem* msg = gMessageSystem;
@@ -719,90 +689,26 @@ S32 LLViewerInventoryCategory::getViewerDescendentCount() const
return descendents_actual;
}
-bool LLViewerInventoryCategory::importFileLocal(LLFILE* fp)
+LLSD LLViewerInventoryCategory::exportLLSD() const
{
- // *NOTE: This buffer size is hard coded into scanf() below.
- char buffer[MAX_STRING]; /* Flawfinder: ignore */
- char keyword[MAX_STRING]; /* Flawfinder: ignore */
- char valuestr[MAX_STRING]; /* Flawfinder: ignore */
+ LLSD cat_data = LLInventoryCategory::exportLLSD();
+ cat_data[INV_OWNER_ID] = mOwnerID;
+ cat_data[INV_VERSION] = mVersion;
- keyword[0] = '\0';
- valuestr[0] = '\0';
- while(!feof(fp))
- {
- if (fgets(buffer, MAX_STRING, fp) == NULL)
- {
- buffer[0] = '\0';
- }
-
- sscanf( /* Flawfinder: ignore */
- buffer, " %254s %254s", keyword, valuestr);
- if(0 == strcmp("{",keyword))
- {
- continue;
- }
- if(0 == strcmp("}", keyword))
- {
- break;
- }
- else if(0 == strcmp("cat_id", keyword))
- {
- mUUID.set(valuestr);
- }
- else if(0 == strcmp("parent_id", keyword))
- {
- mParentUUID.set(valuestr);
- }
- else if(0 == strcmp("type", keyword))
- {
- mType = LLAssetType::lookup(valuestr);
- }
- else if(0 == strcmp("pref_type", keyword))
- {
- mPreferredType = LLFolderType::lookup(valuestr);
- }
- else if(0 == strcmp("name", keyword))
- {
- //strcpy(valuestr, buffer + strlen(keyword) + 3);
- // *NOTE: Not ANSI C, but widely supported.
- sscanf( /* Flawfinder: ignore */
- buffer, " %254s %254[^|]", keyword, valuestr);
- mName.assign(valuestr);
- LLStringUtil::replaceNonstandardASCII(mName, ' ');
- LLStringUtil::replaceChar(mName, '|', ' ');
- }
- else if(0 == strcmp("owner_id", keyword))
- {
- mOwnerID.set(valuestr);
- }
- else if(0 == strcmp("version", keyword))
- {
- sscanf(valuestr, "%d", &mVersion);
- }
- else
- {
- LL_WARNS(LOG_INV) << "unknown keyword '" << keyword
- << "' in inventory import category " << mUUID << LL_ENDL;
- }
- }
- return true;
+ return cat_data;
}
-bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
-{
- std::string uuid_str;
- fprintf(fp, "\tinv_category\t0\n\t{\n");
- mUUID.toString(uuid_str);
- fprintf(fp, "\t\tcat_id\t%s\n", uuid_str.c_str());
- mParentUUID.toString(uuid_str);
- fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
- fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
- fprintf(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType).c_str());
- fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
- mOwnerID.toString(uuid_str);
- fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str());
- fprintf(fp, "\t\tversion\t%d\n", mVersion);
- fprintf(fp,"\t}\n");
+bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)
+{
+ LLInventoryCategory::importLLSD(cat_data);
+ if (cat_data.has(INV_OWNER_ID))
+ {
+ mOwnerID = cat_data[INV_OWNER_ID].asUUID();
+ }
+ if (cat_data.has(INV_VERSION))
+ {
+ setVersion(cat_data[INV_VERSION].asInteger());
+ }
return true;
}
@@ -1098,7 +1004,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
const LLUUID& parent, const LLTransactionID& transaction_id,
const std::string& name,
const std::string& desc, LLAssetType::EType asset_type,
- LLInventoryType::EType inv_type, LLWearableType::EType wtype,
+ LLInventoryType::EType inv_type, U8 subtype,
U32 next_owner_perm,
LLPointer<LLInventoryCallback> cb)
{
@@ -1133,7 +1039,7 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_perm);
msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
- msg->addU8Fast(_PREHASH_WearableType, (U8)wtype);
+ msg->addU8Fast(_PREHASH_WearableType, (U8)subtype);
msg->addStringFast(_PREHASH_Name, server_name);
msg->addStringFast(_PREHASH_Description, desc);
@@ -1147,9 +1053,36 @@ void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent
LLAvatarNameCache::get(avatar_id, &av_name);
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
parent, LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD,
- LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
+ LLInventoryType::IT_CALLINGCARD, NO_INV_SUBTYPE, PERM_MOVE | PERM_TRANSFER, cb);
}
+void create_inventory_wearable(const LLUUID& agent_id, const LLUUID& session_id,
+ const LLUUID& parent, const LLTransactionID& transaction_id,
+ const std::string& name,
+ const std::string& desc, LLAssetType::EType asset_type,
+ LLWearableType::EType wtype,
+ U32 next_owner_perm,
+ LLPointer<LLInventoryCallback> cb)
+{
+ create_inventory_item(agent_id, session_id, parent, transaction_id,
+ name, desc, asset_type, LLInventoryType::IT_WEARABLE, static_cast<U8>(wtype),
+ next_owner_perm, cb);
+}
+
+void create_inventory_settings(const LLUUID& agent_id, const LLUUID& session_id,
+ const LLUUID& parent, const LLTransactionID& transaction_id,
+ const std::string& name,
+ const std::string& desc,
+ LLSettingsType::type_e settype,
+ U32 next_owner_perm,
+ LLPointer<LLInventoryCallback> cb)
+{
+ create_inventory_item(agent_id, session_id, parent, transaction_id,
+ name, desc, LLAssetType::AT_SETTINGS, LLInventoryType::IT_SETTINGS,
+ static_cast<U8>(settype), next_owner_perm, cb);
+}
+
+
void copy_inventory_item(
const LLUUID& agent_id,
const LLUUID& current_owner,
@@ -1701,7 +1634,7 @@ void create_new_item(const std::string& name,
desc,
asset_type,
inv_type,
- NOT_WEARABLE,
+ NO_INV_SUBTYPE,
next_owner_perm,
cb);
}
@@ -1745,7 +1678,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
{
std::string type_name = userdata.asString();
- if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
+ if (("inbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
{
LLFolderType::EType preferred_type = LLFolderType::lookup(type_name);
@@ -1794,6 +1727,32 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
LLInventoryType::IT_GESTURE,
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);
+
+ if ("sky" == type_name)
+ {
+ stype = LLSettingsType::ST_SKY;
+ }
+ else if ("water" == type_name)
+ {
+ stype = LLSettingsType::ST_WATER;
+ }
+ else if ("daycycle" == type_name)
+ {
+ stype = LLSettingsType::ST_DAYCYCLE;
+ }
+ else
+ {
+ LL_ERRS(LOG_INV) << "Unknown settings type: '" << type_name << "'" << LL_ENDL;
+ return;
+ }
+
+ LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+
+ LLSettingsVOBase::createNewInventoryItem(stype, parent_id);
+ }
else
{
// Use for all clothing and body parts. Adding new wearable types requires updating LLWearableDictionary.
@@ -1974,6 +1933,19 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const
return LLWearableType::inventoryFlagsToWearableType(getFlags());
}
+bool LLViewerInventoryItem::isSettingsType() const
+{
+ return (getInventoryType() == LLInventoryType::IT_SETTINGS);
+}
+
+LLSettingsType::type_e LLViewerInventoryItem::getSettingsType() const
+{
+ if (!isSettingsType())
+ {
+ return LLSettingsType::ST_NONE;
+ }
+ return LLSettingsType::fromInventoryFlags(getFlags());
+}
time_t LLViewerInventoryItem::getCreationDate() const
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index b3053e365b..24b632632b 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -31,6 +31,7 @@
#include "llframetimer.h"
#include "llwearable.h"
#include "llinitdestroyclass.h" //for LLDestroyClass
+#include "llinventorysettings.h"
#include <boost/signals2.hpp> // boost::signals2::trackable
@@ -74,6 +75,9 @@ public:
virtual LLInventoryType::EType getInventoryType() const;
virtual bool isWearableType() const;
virtual LLWearableType::EType getWearableType() const;
+ virtual bool isSettingsType() const;
+ virtual LLSettingsType::type_e getSettingsType() const;
+
virtual U32 getFlags() const;
virtual time_t getCreationDate() const;
virtual U32 getCRC32() const; // really more of a checksum.
@@ -127,14 +131,8 @@ public:
virtual void packMessage(LLMessageSystem* msg) const;
virtual BOOL unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
virtual BOOL unpackMessage(const LLSD& item);
- virtual BOOL importFile(LLFILE* fp);
virtual BOOL importLegacyStream(std::istream& input_stream);
- // file handling on the viewer. These are not meant for anything
- // other than cacheing.
- bool exportFileLocal(LLFILE* fp) const;
- bool importFileLocal(LLFILE* fp);
-
// new methods
BOOL isFinished() const { return mIsComplete; }
void setComplete(BOOL complete) { mIsComplete = complete; }
@@ -222,10 +220,9 @@ public:
// How many descendents do we currently have information for in the InventoryModel?
S32 getViewerDescendentCount() const;
- // file handling on the viewer. These are not meant for anything
- // other than caching.
- bool exportFileLocal(LLFILE* fp) const;
- bool importFileLocal(LLFILE* fp);
+ LLSD exportLLSD() const;
+ bool importLLSD(const LLSD& cat_data);
+
void determineFolderType();
void changeType(LLFolderType::EType new_folder_type);
virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
@@ -295,7 +292,7 @@ public:
// virtual
void fire(const LLUUID& item_id)
-{
+ {
mFireFunc(item_id);
}
@@ -336,17 +333,32 @@ public:
extern LLInventoryCallbackManager gInventoryCallbacks;
-#define NOT_WEARABLE (LLWearableType::EType)0
+const U8 NO_INV_SUBTYPE{ 0 };
// *TODO: Find a home for these
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
const LLUUID& parent, const LLTransactionID& transaction_id,
const std::string& name,
const std::string& desc, LLAssetType::EType asset_type,
- LLInventoryType::EType inv_type, LLWearableType::EType wtype,
+ LLInventoryType::EType inv_type, U8 subtype,
U32 next_owner_perm,
LLPointer<LLInventoryCallback> cb);
+void create_inventory_wearable(const LLUUID& agent_id, const LLUUID& session_id,
+ const LLUUID& parent, const LLTransactionID& transaction_id,
+ const std::string& name,
+ const std::string& desc, LLAssetType::EType asset_type,
+ LLWearableType::EType wtype,
+ U32 next_owner_perm,
+ LLPointer<LLInventoryCallback> cb);
+
+void create_inventory_settings(const LLUUID& agent_id, const LLUUID& session_id,
+ const LLUUID& parent, const LLTransactionID& transaction_id,
+ const std::string& name, const std::string& desc,
+ LLSettingsType::type_e settype,
+ U32 next_owner_perm, LLPointer<LLInventoryCallback> cb);
+
+
void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent = LLUUID::null, LLPointer<LLInventoryCallback> cb=NULL);
/**
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index b7bd131246..9653e80b53 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -141,10 +141,11 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
//----------------------------------------------------------------
// render children
//----------------------------------------------------------------
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
+ for (LLJoint* j : mChildren)
{
- LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ // LLViewerJoint is derived from LLAvatarJoint,
+ // all children of LLAvatarJoint are assumed to be LLAvatarJoint
+ LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(j);
F32 jointLOD = joint->getLOD();
if (pixelArea >= jointLOD || sDisableLOD)
{
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 43a81ada49..63ad708e59 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -56,7 +56,7 @@
#include "m4math.h"
#include "llmatrix4a.h"
-#if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS
+#if !LL_DARWIN && !LL_LINUX
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
extern PFNGLWEIGHTFVARBPROC glWeightfvARB;
extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB;
@@ -112,7 +112,7 @@ void LLViewerJointMesh::uploadJointMatrices()
S32 joint_num;
LLPolyMesh *reference_mesh = mMesh->getReferenceMesh();
LLDrawPool *poolp = mFace ? mFace->getPool() : NULL;
- BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE;
+ BOOL hardware_skinning = (poolp && poolp->getShaderLevel() > 0) ? TRUE : FALSE;
//calculate joint matrices
for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.size(); joint_num++)
@@ -246,14 +246,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
stop_glerror();
- LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny);
+ LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny);
//----------------------------------------------------------------
// setup current texture
//----------------------------------------------------------------
llassert( !(mTexture.notNull() && mLayerSet) ); // mutually exclusive
- LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);
if (mTestImageName)
{
@@ -280,22 +279,15 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
}
}
- else
- if ( !is_dummy && mTexture.notNull() )
+ else if ( !is_dummy && mTexture.notNull() )
{
- if(mTexture->hasGLTexture())
- {
- old_mode = mTexture->getAddressMode();
- }
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
- gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
else
{
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
}
-
U32 mask = sRenderMask;
U32 start = mMesh->mFaceVertexOffset;
@@ -307,14 +299,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
if (mMesh->hasWeights())
{
- if ((mFace->getPool()->getVertexShaderLevel() > 0))
+ if ((mFace->getPool()->getShaderLevel() > 0))
{
if (first_pass)
{
uploadJointMatrices();
}
mask = mask | LLVertexBuffer::MAP_WEIGHT;
- if (mFace->getPool()->getVertexShaderLevel() > 1)
+ if (mFace->getPool()->getShaderLevel() > 1)
{
mask = mask | LLVertexBuffer::MAP_CLOTHWEIGHT;
}
@@ -341,12 +333,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
}
- if (mTexture.notNull() && !is_dummy)
- {
- gGL.getTexUnit(diffuse_channel)->bind(mTexture);
- gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode);
- }
-
return triangle_count;
}
@@ -390,7 +376,7 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
}
LLDrawPool *poolp = mFace->getPool();
- BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE;
+ BOOL hardware_skinning = (poolp && poolp->getShaderLevel() > 0) ? TRUE : FALSE;
if (!hardware_skinning && terse_update)
{ //no need to do terse updates if we're doing software vertex skinning
@@ -538,7 +524,7 @@ void LLViewerJointMesh::updateJointGeometry()
&& mFace
&& mMesh->hasWeights()
&& mFace->getVertexBuffer()
- && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0))
+ && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0))
{
return;
}
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index e44d80b7ce..e35cb26ce1 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -36,10 +36,19 @@
#include "lltoolmgr.h"
#include "llselectmgr.h"
#include "llviewermenu.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llfocusmgr.h"
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// Require DirectInput version 8
+#define DIRECTINPUT_VERSION 0x0800
+
+#include <dinput.h>
+#endif
+
// ----------------------------------------------------------------------------
// Constants
@@ -62,6 +71,164 @@ F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
#define MAX_SPACENAVIGATOR_INPUT 3000.0f
#define MAX_JOYSTICK_INPUT_VALUE MAX_SPACENAVIGATOR_INPUT
+
+#if LIB_NDOF
+std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
+{
+ if (! ptr)
+ {
+ return out << "nullptr";
+ }
+ out << "NDOF_Device{ ";
+ out << "axes [";
+ const char* delim = "";
+ for (short axis = 0; axis < ptr->axes_count; ++axis)
+ {
+ out << delim << ptr->axes[axis];
+ delim = ", ";
+ }
+ out << "]";
+ out << ", buttons [";
+ delim = "";
+ for (short button = 0; button < ptr->btn_count; ++button)
+ {
+ out << delim << ptr->buttons[button];
+ delim = ", ";
+ }
+ out << "]";
+ out << ", range " << ptr->axes_min << ':' << ptr->axes_max;
+ // If we don't coerce these to unsigned, they're streamed as characters,
+ // e.g. ctrl-A or nul.
+ out << ", absolute " << unsigned(ptr->absolute);
+ out << ", valid " << unsigned(ptr->valid);
+ out << ", manufacturer '" << ptr->manufacturer << "'";
+ out << ", product '" << ptr->product << "'";
+ out << ", private " << ptr->private_data;
+ out << " }";
+ return out;
+}
+#endif // LIB_NDOF
+
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// this should reflect ndof and set axises, see ndofdev_win.cpp from ndof package
+BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst, VOID* user_data)
+{
+ if (inst->dwType & DIDFT_AXIS)
+ {
+ LPDIRECTINPUTDEVICE8 device = *((LPDIRECTINPUTDEVICE8 *)user_data);
+ DIPROPRANGE diprg;
+ diprg.diph.dwSize = sizeof(DIPROPRANGE);
+ diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ diprg.diph.dwHow = DIPH_BYID;
+ diprg.diph.dwObj = inst->dwType; // specify the enumerated axis
+
+ // Set the range for the axis
+ diprg.lMin = (long)-MAX_JOYSTICK_INPUT_VALUE;
+ diprg.lMax = (long)+MAX_JOYSTICK_INPUT_VALUE;
+ HRESULT hr = device->SetProperty(DIPROP_RANGE, &diprg.diph);
+
+ if (FAILED(hr))
+ {
+ return DIENUM_STOP;
+ }
+ }
+
+ return DIENUM_CONTINUE;
+}
+
+BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
+{
+ // Note: If a single device can function as more than one DirectInput
+ // device type, it is enumerated as each device type that it supports.
+ // Capable of detecting devices like Oculus Rift
+ if (device_instance_ptr)
+ {
+ std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
+
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+
+ bool init_device = false;
+ if (guid.isBinary())
+ {
+ std::vector<U8> bin_bucket = guid.asBinary();
+ init_device = memcmp(&bin_bucket[0], &device_instance_ptr->guidInstance, sizeof(GUID)) == 0;
+ }
+ else
+ {
+ // It might be better to init space navigator here, but if system doesn't has one,
+ // ndof will pick a random device, it is simpler to pick first device now to have an id
+ init_device = true;
+ }
+
+ if (init_device)
+ {
+ LL_DEBUGS("Joystick") << "Found and attempting to use device: " << product_name << LL_ENDL;
+ LPDIRECTINPUT8 di8_interface = *((LPDIRECTINPUT8 *)gViewerWindow->getWindow()->getDirectInput8());
+ LPDIRECTINPUTDEVICE8 device = NULL;
+
+ HRESULT status = di8_interface->CreateDevice(
+ device_instance_ptr->guidInstance, // REFGUID rguid,
+ &device, // LPDIRECTINPUTDEVICE * lplpDirectInputDevice,
+ NULL // LPUNKNOWN pUnkOuter
+ );
+
+ if (status == DI_OK)
+ {
+ // prerequisite for aquire()
+ LL_DEBUGS("Joystick") << "Device created" << LL_ENDL;
+ status = device->SetDataFormat(&c_dfDIJoystick); // c_dfDIJoystick2
+ }
+
+ if (status == DI_OK)
+ {
+ // set properties
+ LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
+ status = device->EnumObjects(EnumObjectsCallback, &device, DIDFT_ALL);
+ }
+
+ if (status == DI_OK)
+ {
+ LL_DEBUGS("Joystick") << "Properties updated" << LL_ENDL;
+
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+ LLViewerJoystick::getInstance()->initDevice(&device, product_name, LLSD(data));
+ return DIENUM_STOP;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("Joystick") << "Found device: " << product_name << LL_ENDL;
+ }
+ }
+ return DIENUM_CONTINUE;
+}
+
+// Windows guids
+// This is GUID2 so teoretically it can be memcpy copied into LLUUID
+void guid_from_string(GUID &guid, const std::string &input)
+{
+ CLSIDFromString(utf8str_to_utf16str(input).c_str(), &guid);
+}
+
+std::string string_from_guid(const GUID &guid)
+{
+ OLECHAR* guidString; //wchat
+ StringFromCLSID(guid, &guidString);
+
+ // use guidString...
+
+ std::string res = utf16str_to_utf8str(llutf16string(guidString));
+ // ensure memory is freed
+ ::CoTaskMemFree(guidString);
+
+ return res;
+}
+#endif
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::updateEnabled(bool autoenable)
{
@@ -71,7 +238,8 @@ void LLViewerJoystick::updateEnabled(bool autoenable)
}
else
{
- if (isLikeSpaceNavigator() && autoenable)
+ // autoenable if user specifically chose this device
+ if (autoenable && (isLikeSpaceNavigator() || isDeviceUUIDSet()))
{
gSavedSettings.setBOOL("JoystickEnabled", TRUE );
}
@@ -107,11 +275,11 @@ NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mDriverState == JDS_UNINITIALIZED)
{
- LL_INFOS() << "HotPlugAddCallback: will use device:" << LL_ENDL;
- ndof_dump(dev);
+ LL_INFOS("Joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
+ ndof_dump(stderr, dev);
joystick->mNdofDev = dev;
- joystick->mDriverState = JDS_INITIALIZED;
- res = NDOF_KEEP_HOTPLUGGED;
+ joystick->mDriverState = JDS_INITIALIZED;
+ res = NDOF_KEEP_HOTPLUGGED;
}
joystick->updateEnabled(true);
return res;
@@ -125,9 +293,9 @@ void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mNdofDev == dev)
{
- LL_INFOS() << "HotPlugRemovalCallback: joystick->mNdofDev="
+ LL_INFOS("Joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
<< joystick->mNdofDev << "; removed device:" << LL_ENDL;
- ndof_dump(dev);
+ ndof_dump(stderr, dev);
joystick->mDriverState = JDS_UNINITIALIZED;
}
joystick->updateEnabled(true);
@@ -152,6 +320,8 @@ LLViewerJoystick::LLViewerJoystick()
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why?
+
+ mLastDeviceUUID = LLSD::Integer(1);
}
// -----------------------------------------------------------------------------
@@ -170,12 +340,14 @@ void LLViewerJoystick::init(bool autoenable)
static bool libinit = false;
mDriverState = JDS_INITIALIZING;
+ loadDeviceIdFromSettings();
+
if (libinit == false)
{
// Note: The HotPlug callbacks are not actually getting called on Windows
if (ndof_libinit(HotPlugAddCallback,
HotPlugRemovalCallback,
- NULL))
+ gViewerWindow->getWindow()->getDirectInput8()))
{
mDriverState = JDS_UNINITIALIZED;
}
@@ -192,35 +364,33 @@ void LLViewerJoystick::init(bool autoenable)
if (libinit)
{
if (mNdofDev)
- {
- // Different joysticks will return different ranges of raw values.
- // Since we want to handle every device in the same uniform way,
- // we initialize the mNdofDev struct and we set the range
- // of values we would like to receive.
- //
- // HACK: On Windows, libndofdev passes our range to DI with a
- // SetProperty call. This works but with one notable exception, the
- // SpaceNavigator, who doesn't seem to care about the SetProperty
- // call. In theory, we should handle this case inside libndofdev.
- // However, the range we're setting here is arbitrary anyway,
- // so let's just use the SpaceNavigator range for our purposes.
- mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
- mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
-
- // libndofdev could be used to return deltas. Here we choose to
- // just have the absolute values instead.
- mNdofDev->absolute = 1;
-
- // init & use the first suitable NDOF device found on the USB chain
- if (ndof_init_first(mNdofDev, NULL))
- {
- mDriverState = JDS_UNINITIALIZED;
- LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
- }
- else
- {
- mDriverState = JDS_INITIALIZED;
- }
+ {
+ // di8_devices_callback callback is immediate and happens in scope of getInputDevices()
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices from windows, init first suitable one
+ mLastDeviceUUID = LLSD();
+ void *preffered_device = NULL;
+ initDevice(preffered_device);
+ }
+
+ if (mDriverState == JDS_INITIALIZING)
+ {
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
+ }
}
else
{
@@ -258,20 +428,104 @@ void LLViewerJoystick::init(bool autoenable)
{
// No device connected, don't change any settings
}
-
- LL_INFOS() << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
+
+ LL_INFOS("Joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
<< mNdofDev << "; libinit=" << libinit << LL_ENDL;
#endif
}
+void LLViewerJoystick::initDevice(LLSD &guid)
+{
+#if LIB_NDOF
+ mLastDeviceUUID = guid;
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+
+ mDriverState = JDS_INITIALIZING;
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices from windows, init first suitable one
+ void *preffered_device = NULL;
+ mLastDeviceUUID = LLSD();
+ initDevice(preffered_device);
+ }
+
+ if (mDriverState == JDS_INITIALIZING)
+ {
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
+ }
+#endif
+}
+
+void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
+{
+#if LIB_NDOF
+ mLastDeviceUUID = guid;
+
+ strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product));
+ mNdofDev->manufacturer[0] = '\0';
+
+ initDevice(preffered_device);
+#endif
+}
+
+void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
+{
+#if LIB_NDOF
+ // Different joysticks will return different ranges of raw values.
+ // Since we want to handle every device in the same uniform way,
+ // we initialize the mNdofDev struct and we set the range
+ // of values we would like to receive.
+ //
+ // HACK: On Windows, libndofdev passes our range to DI with a
+ // SetProperty call. This works but with one notable exception, the
+ // SpaceNavigator, who doesn't seem to care about the SetProperty
+ // call. In theory, we should handle this case inside libndofdev.
+ // However, the range we're setting here is arbitrary anyway,
+ // so let's just use the SpaceNavigator range for our purposes.
+ mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
+ mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
+
+ // libndofdev could be used to return deltas. Here we choose to
+ // just have the absolute values instead.
+ mNdofDev->absolute = 1;
+ // init & use the first suitable NDOF device found on the USB chain
+ // On windows preffered_device needs to be a pointer to LPDIRECTINPUTDEVICE8
+ if (ndof_init_first(mNdofDev, preffered_device))
+ {
+ mDriverState = JDS_UNINITIALIZED;
+ LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
+ }
+ else
+ {
+ mDriverState = JDS_INITIALIZED;
+ }
+#endif
+}
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::terminate()
{
#if LIB_NDOF
-
- ndof_libcleanup();
- LL_INFOS() << "Terminated connection with NDOF device." << LL_ENDL;
- mDriverState = JDS_UNINITIALIZED;
+ if (mNdofDev != NULL)
+ {
+ ndof_libcleanup(); // frees alocated memory in mNdofDev
+ mDriverState = JDS_UNINITIALIZED;
+ mNdofDev = NULL;
+ LL_INFOS("Joystick") << "Terminated connection with NDOF device." << LL_ENDL;
+ }
#endif
}
@@ -1061,6 +1315,74 @@ void LLViewerJoystick::scanJoystick()
}
// -----------------------------------------------------------------------------
+bool LLViewerJoystick::isDeviceUUIDSet()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary
+ return mLastDeviceUUID.isBinary();
+#else
+ return false;
+#endif
+}
+
+LLSD LLViewerJoystick::getDeviceUUID()
+{
+ return mLastDeviceUUID;
+}
+
+std::string LLViewerJoystick::getDeviceUUIDString()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // Might be simpler to just convert _GUID into string everywhere, store and compare as string
+ if (mLastDeviceUUID.isBinary())
+ {
+ S32 size = sizeof(GUID);
+ LLSD::Binary data = mLastDeviceUUID.asBinary();
+ GUID guid;
+ memcpy(&guid, &data[0], size);
+ return string_from_guid(guid);
+ }
+ else
+ {
+ return std::string();
+ }
+#else
+ return std::string();
+ // return mLastDeviceUUID;
+#endif
+}
+
+void LLViewerJoystick::loadDeviceIdFromSettings()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // We can't save binary data to gSavedSettings, somebody editing the file will corrupt it,
+ // so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy)
+ // and here we need to convert it back to binary from string
+ std::string device_string = gSavedSettings.getString("JoystickDeviceUUID");
+ if (device_string.empty())
+ {
+ mLastDeviceUUID = LLSD();
+ }
+ else
+ {
+ LL_DEBUGS("Joystick") << "Looking for device by id: " << device_string << LL_ENDL;
+ GUID guid;
+ guid_from_string(guid, device_string);
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &guid /*POD _GUID*/, size);
+ // We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2
+ // and any data MAC will need for device selection
+ mLastDeviceUUID = LLSD(data);
+ }
+#else
+ mLastDeviceUUID = LLSD();
+ //mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID");
+#endif
+}
+
+// -----------------------------------------------------------------------------
std::string LLViewerJoystick::getDescription()
{
std::string res;
@@ -1075,7 +1397,7 @@ std::string LLViewerJoystick::getDescription()
bool LLViewerJoystick::isLikeSpaceNavigator() const
{
-#if LIB_NDOF
+#if LIB_NDOF
return (isJoystickInitialized()
&& (strncmp(mNdofDev->product, "SpaceNavigator", 14) == 0
|| strncmp(mNdofDev->product, "SpaceExplorer", 13) == 0
@@ -1099,10 +1421,10 @@ void LLViewerJoystick::setSNDefaults()
const float platformScaleAvXZ = 2.f;
const bool is_3d_cursor = true;
#endif
-
+
//gViewerWindow->alertXml("CacheWillClear");
- LL_INFOS() << "restoring SpaceNavigator defaults..." << LL_ENDL;
-
+ LL_INFOS("Joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
+
gSavedSettings.setS32("JoystickAxis0", 1); // z (at)
gSavedSettings.setS32("JoystickAxis1", 0); // x (slide)
gSavedSettings.setS32("JoystickAxis2", 2); // y (up)
@@ -1110,11 +1432,11 @@ void LLViewerJoystick::setSNDefaults()
gSavedSettings.setS32("JoystickAxis4", 3); // roll
gSavedSettings.setS32("JoystickAxis5", 5); // yaw
gSavedSettings.setS32("JoystickAxis6", -1);
-
+
gSavedSettings.setBOOL("Cursor3D", is_3d_cursor);
gSavedSettings.setBOOL("AutoLeveling", true);
gSavedSettings.setBOOL("ZoomDirect", false);
-
+
gSavedSettings.setF32("AvatarAxisScale0", 1.f * platformScaleAvXZ);
gSavedSettings.setF32("AvatarAxisScale1", 1.f * platformScaleAvXZ);
gSavedSettings.setF32("AvatarAxisScale2", 1.f);
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 016b435ee8..782c523d4f 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -50,6 +50,9 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
public:
void init(bool autoenable);
+ void initDevice(LLSD &guid);
+ void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
+ void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
void terminate();
void updateStatus();
@@ -68,8 +71,11 @@ public:
void setOverrideCamera(bool val);
bool toggleFlycam();
void setSNDefaults();
+ bool isDeviceUUIDSet();
+ LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search
+ std::string getDeviceUUIDString(); // converted readable value for settings
std::string getDescription();
-
+
protected:
void updateEnabled(bool autoenable);
void handleRun(F32 inc);
@@ -80,6 +86,7 @@ protected:
void agentYaw(F32 yaw_inc);
void agentJump();
void resetDeltas(S32 axis[]);
+ void loadDeviceIdFromSettings();
#if LIB_NDOF
static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev);
static void HotPlugRemovalCallback(NDOF_Device *dev);
@@ -95,6 +102,7 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
+ LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
static F32 sLastDelta[7];
static F32 sDelta[7];
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
deleted file mode 100644
index e930eb20d3..0000000000
--- a/indra/newview/llviewerkeyboard.cpp
+++ /dev/null
@@ -1,1032 +0,0 @@
-/**
- * @file llviewerkeyboard.cpp
- * @brief LLViewerKeyboard class implementation
- *
- * $LicenseInfo:firstyear=2005&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 "llappviewer.h"
-#include "llfloaterreg.h"
-#include "llviewerkeyboard.h"
-#include "llmath.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llfloaterimnearbychat.h"
-#include "llviewercontrol.h"
-#include "llfocusmgr.h"
-#include "llmorphview.h"
-#include "llmoveview.h"
-#include "lltoolfocus.h"
-#include "llviewerwindow.h"
-#include "llvoavatarself.h"
-#include "llfloatercamera.h"
-#include "llinitparam.h"
-
-//
-// Constants
-//
-
-const F32 FLY_TIME = 0.5f;
-const F32 FLY_FRAMES = 4;
-
-const F32 NUDGE_TIME = 0.25f; // in seconds
-const S32 NUDGE_FRAMES = 2;
-const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed
-
-struct LLKeyboardActionRegistry
-: public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry>
-{
- LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);
-};
-
-LLViewerKeyboard gViewerKeyboard;
-
-void agent_jump( EKeystate s )
-{
- static BOOL first_fly_attempt(TRUE);
- if (KEYSTATE_UP == s)
- {
- first_fly_attempt = TRUE;
- return;
- }
- F32 time = gKeyboard->getCurKeyElapsedTime();
- S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
- if( time < FLY_TIME
- || frame_count <= FLY_FRAMES
- || gAgent.upGrabbed()
- || !gSavedSettings.getBOOL("AutomaticFly"))
- {
- gAgent.moveUp(1);
- }
- else
- {
- gAgent.setFlying(TRUE, first_fly_attempt);
- first_fly_attempt = FALSE;
- gAgent.moveUp(1);
- }
-}
-
-void agent_push_down( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgent.moveUp(-1);
-}
-
-static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
-{
- if (gAgent.mDoubleTapRunMode == mode &&
- gAgent.getRunning() &&
- !gAgent.getAlwaysRun())
- {
- // Turn off temporary running.
- gAgent.clearRunning();
- gAgent.sendWalkRun(gAgent.getRunning());
- }
-}
-
-static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
-{
- if (KEYSTATE_UP == s)
- {
- // Note: in case shift is already released, slide left/right run
- // will be released in agent_turn_left()/agent_turn_right()
- agent_check_temporary_run(mode);
- }
- else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
- KEYSTATE_DOWN == s &&
- !gAgent.getRunning())
- {
- if (gAgent.mDoubleTapRunMode == mode &&
- gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME)
- {
- // Same walk-key was pushed again quickly; this is a
- // double-tap so engage temporary running.
- gAgent.setRunning();
- gAgent.sendWalkRun(gAgent.getRunning());
- }
-
- // Pressing any walk-key resets the double-tap timer
- gAgent.mDoubleTapRunTimer.reset();
- gAgent.mDoubleTapRunMode = mode;
- }
-}
-
-static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
-{
- agent_handle_doubletap_run(s, mode);
- if (KEYSTATE_UP == s) return;
-
- F32 time = gKeyboard->getCurKeyElapsedTime();
- S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
- if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
- {
- gAgent.moveAtNudge(direction);
- }
- else
- {
- gAgent.moveAt(direction);
- }
-}
-
-void camera_move_forward( EKeystate s );
-
-void agent_push_forward( EKeystate s )
-{
- if(gAgent.isMovementLocked()) return;
-
- //in free camera control mode we need to intercept keyboard events for avatar movements
- if (LLFloaterCamera::inFreeCameraMode())
- {
- camera_move_forward(s);
- }
- else
- {
- agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
- }
-}
-
-void camera_move_backward( EKeystate s );
-
-void agent_push_backward( EKeystate s )
-{
- if(gAgent.isMovementLocked()) return;
-
- //in free camera control mode we need to intercept keyboard events for avatar movements
- if (LLFloaterCamera::inFreeCameraMode())
- {
- camera_move_backward(s);
- }
- else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook"))
- {
- gAgentCamera.changeCameraToThirdPerson();
- }
- else
- {
- agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
- }
-}
-
-static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
-{
- agent_handle_doubletap_run(s, mode);
- if( KEYSTATE_UP == s ) return;
- F32 time = gKeyboard->getCurKeyElapsedTime();
- S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
- if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
- {
- gAgent.moveLeftNudge(direction);
- }
- else
- {
- gAgent.moveLeft(direction);
- }
-}
-
-
-void agent_slide_left( EKeystate s )
-{
- if(gAgent.isMovementLocked()) return;
- agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT);
-}
-
-
-void agent_slide_right( EKeystate s )
-{
- if(gAgent.isMovementLocked()) return;
- agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
-}
-
-void camera_spin_around_cw( EKeystate s );
-
-void agent_turn_left( EKeystate s )
-{
- //in free camera control mode we need to intercept keyboard events for avatar movements
- if (LLFloaterCamera::inFreeCameraMode())
- {
- camera_spin_around_cw(s);
- return;
- }
-
- if(gAgent.isMovementLocked()) return;
-
- if (LLToolCamera::getInstance()->mouseSteerMode())
- {
- agent_slide_left(s);
- }
- else
- {
- if (KEYSTATE_UP == s)
- {
- // Check temporary running. In case user released 'left' key with shift already released.
- agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
- return;
- }
- F32 time = gKeyboard->getCurKeyElapsedTime();
- gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
- }
-}
-
-void camera_spin_around_ccw( EKeystate s );
-
-void agent_turn_right( EKeystate s )
-{
- //in free camera control mode we need to intercept keyboard events for avatar movements
- if (LLFloaterCamera::inFreeCameraMode())
- {
- camera_spin_around_ccw(s);
- return;
- }
-
- if(gAgent.isMovementLocked()) return;
-
- if (LLToolCamera::getInstance()->mouseSteerMode())
- {
- agent_slide_right(s);
- }
- else
- {
- if (KEYSTATE_UP == s)
- {
- // Check temporary running. In case user released 'right' key with shift already released.
- agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
- return;
- }
- F32 time = gKeyboard->getCurKeyElapsedTime();
- gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
- }
-}
-
-void agent_look_up( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgent.movePitch(-1);
- //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
-}
-
-
-void agent_look_down( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgent.movePitch(1);
- //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
-}
-
-void agent_toggle_fly( EKeystate s )
-{
- // Only catch the edge
- if (KEYSTATE_DOWN == s )
- {
- LLAgent::toggleFlying();
- }
-}
-
-F32 get_orbit_rate()
-{
- F32 time = gKeyboard->getCurKeyElapsedTime();
- if( time < NUDGE_TIME )
- {
- F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
- //LL_INFOS() << rate << LL_ENDL;
- return rate;
- }
- else
- {
- return 1;
- }
-}
-
-void camera_spin_around_ccw( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
-}
-
-
-void camera_spin_around_cw( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitRightKey( get_orbit_rate() );
-}
-
-void camera_spin_around_ccw_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return;
- if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
- {
- //send keystrokes, but do not change camera
- agent_turn_right(s);
- }
- else
- {
- //change camera but do not send keystrokes
- gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
- }
-}
-
-
-void camera_spin_around_cw_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return;
- if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
- {
- //send keystrokes, but do not change camera
- agent_turn_left(s);
- }
- else
- {
- //change camera but do not send keystrokes
- gAgentCamera.setOrbitRightKey( get_orbit_rate() );
- }
-}
-
-
-void camera_spin_over( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitUpKey( get_orbit_rate() );
-}
-
-
-void camera_spin_under( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitDownKey( get_orbit_rate() );
-}
-
-void camera_spin_over_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled())
- {
- //send keystrokes, but do not change camera
- agent_jump(s);
- }
- else
- {
- //change camera but do not send keystrokes
- gAgentCamera.setOrbitUpKey( get_orbit_rate() );
- }
-}
-
-
-void camera_spin_under_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled())
- {
- //send keystrokes, but do not change camera
- agent_push_down(s);
- }
- else
- {
- //change camera but do not send keystrokes
- gAgentCamera.setOrbitDownKey( get_orbit_rate() );
- }
-}
-
-void camera_move_forward( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitInKey( get_orbit_rate() );
-}
-
-
-void camera_move_backward( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitOutKey( get_orbit_rate() );
-}
-
-void camera_move_forward_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return;
- if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
- {
- agent_push_forward(s);
- }
- else
- {
- gAgentCamera.setOrbitInKey( get_orbit_rate() );
- }
-}
-
-
-void camera_move_backward_sitting( EKeystate s )
-{
- if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return;
-
- if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
- {
- agent_push_backward(s);
- }
- else
- {
- gAgentCamera.setOrbitOutKey( get_orbit_rate() );
- }
-}
-
-void camera_pan_up( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanUpKey( get_orbit_rate() );
-}
-
-void camera_pan_down( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanDownKey( get_orbit_rate() );
-}
-
-void camera_pan_left( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanLeftKey( get_orbit_rate() );
-}
-
-void camera_pan_right( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanRightKey( get_orbit_rate() );
-}
-
-void camera_pan_in( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanInKey( get_orbit_rate() );
-}
-
-void camera_pan_out( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setPanOutKey( get_orbit_rate() );
-}
-
-void camera_move_forward_fast( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitInKey(2.5f);
-}
-
-void camera_move_backward_fast( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gAgentCamera.unlockView();
- gAgentCamera.setOrbitOutKey(2.5f);
-}
-
-
-void edit_avatar_spin_ccw( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
- //gMorphView->orbitLeft( get_orbit_rate() );
-}
-
-
-void edit_avatar_spin_cw( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitRightKey( get_orbit_rate() );
- //gMorphView->orbitRight( get_orbit_rate() );
-}
-
-void edit_avatar_spin_over( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitUpKey( get_orbit_rate() );
- //gMorphView->orbitUp( get_orbit_rate() );
-}
-
-
-void edit_avatar_spin_under( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitDownKey( get_orbit_rate() );
- //gMorphView->orbitDown( get_orbit_rate() );
-}
-
-void edit_avatar_move_forward( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitInKey( get_orbit_rate() );
- //gMorphView->orbitIn();
-}
-
-
-void edit_avatar_move_backward( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- gMorphView->setCameraDrivenByKeys( TRUE );
- gAgentCamera.setOrbitOutKey( get_orbit_rate() );
- //gMorphView->orbitOut();
-}
-
-void stop_moving( EKeystate s )
-{
- if( KEYSTATE_UP == s ) return;
- // stop agent
- gAgent.setControlFlags(AGENT_CONTROL_STOP);
-
- // cancel autopilot
- gAgent.stopAutoPilot();
-}
-
-void start_chat( EKeystate s )
-{
- if (LLAppViewer::instance()->quitRequested())
- {
- return; // can't talk, gotta go, kthxbye!
- }
-
- // start chat
- LLFloaterIMNearbyChat::startChat(NULL);
-}
-
-void start_gesture( EKeystate s )
-{
- LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
- if (KEYSTATE_UP == s &&
- ! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
- {
- if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
- {
- // No existing chat in chat editor, insert '/'
- LLFloaterIMNearbyChat::startChat("/");
- }
- else
- {
- // Don't overwrite existing text in chat editor
- LLFloaterIMNearbyChat::startChat(NULL);
- }
- }
-}
-
-#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION);
-REGISTER_KEYBOARD_ACTION("jump", agent_jump);
-REGISTER_KEYBOARD_ACTION("push_down", agent_push_down);
-REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward);
-REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward);
-REGISTER_KEYBOARD_ACTION("look_up", agent_look_up);
-REGISTER_KEYBOARD_ACTION("look_down", agent_look_down);
-REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly);
-REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left);
-REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right);
-REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left);
-REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right);
-REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw);
-REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw);
-REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
-REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting);
-REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over);
-REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under);
-REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting);
-REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting);
-REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward);
-REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward);
-REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting);
-REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting);
-REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up);
-REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down);
-REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left);
-REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right);
-REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in);
-REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out);
-REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast);
-REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under);
-REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward);
-REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward);
-REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving);
-REGISTER_KEYBOARD_ACTION("start_chat", start_chat);
-REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture);
-#undef REGISTER_KEYBOARD_ACTION
-
-LLViewerKeyboard::LLViewerKeyboard()
-{
- for (S32 i = 0; i < MODE_COUNT; i++)
- {
- mBindingCount[i] = 0;
- }
-
- for (S32 i = 0; i < KEY_COUNT; i++)
- {
- mKeyHandledByUI[i] = FALSE;
- }
- // we want the UI to never see these keys so that they can always control the avatar/camera
- for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++)
- {
- mKeysSkippedByUI.insert(k);
- }
-}
-
-BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode)
-{
- if (string == "FIRST_PERSON")
- {
- *mode = MODE_FIRST_PERSON;
- return TRUE;
- }
- else if (string == "THIRD_PERSON")
- {
- *mode = MODE_THIRD_PERSON;
- return TRUE;
- }
- else if (string == "EDIT")
- {
- *mode = MODE_EDIT;
- return TRUE;
- }
- else if (string == "EDIT_AVATAR")
- {
- *mode = MODE_EDIT_AVATAR;
- return TRUE;
- }
- else if (string == "SITTING")
- {
- *mode = MODE_SITTING;
- return TRUE;
- }
- else
- {
- *mode = MODE_THIRD_PERSON;
- return FALSE;
- }
-}
-
-BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated)
-{
- // check for re-map
- EKeyboardMode mode = gViewerKeyboard.getMode();
- U32 keyidx = (translated_mask<<16) | translated_key;
- key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx);
- if (iter != mRemapKeys[mode].end())
- {
- translated_key = (iter->second) & 0xff;
- translated_mask = (iter->second)>>16;
- }
-
- // No repeats of F-keys
- BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12);
- if (!repeatable_key && repeated)
- {
- return FALSE;
- }
-
- LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL;
- // skip skipped keys
- if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end())
- {
- mKeyHandledByUI[translated_key] = FALSE;
- LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL;
- }
- else
- {
- // it is sufficient to set this value once per call to handlekey
- // without clearing it, as it is only used in the subsequent call to scanKey
- mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
- // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
- // NOT whether some UI shortcut wishes to handle the keypress
-
- }
- return mKeyHandledByUI[translated_key];
-}
-
-BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask)
-{
- return gViewerWindow->handleKeyUp(translated_key, translated_mask);
-}
-
-BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
-{
- S32 index;
- typedef boost::function<void(EKeystate)> function_t;
- function_t function = NULL;
- std::string name;
-
- // Allow remapping of F2-F12
- if (function_name[0] == 'F')
- {
- int c1 = function_name[1] - '0';
- int c2 = function_name[2] ? function_name[2] - '0' : -1;
- if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9)
- {
- int idx = c1;
- if (c2 >= 0)
- idx = idx*10 + c2;
- if (idx >=2 && idx <= 12)
- {
- U32 keyidx = ((mask<<16)|key);
- (mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1)));
- return TRUE;
- }
- }
- }
-
- // Not remapped, look for a function
-
- function_t* result = LLKeyboardActionRegistry::getValue(function_name);
- if (result)
- {
- function = *result;
- }
-
- if (!function)
- {
- LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
- return FALSE;
- }
-
- // check for duplicate first and overwrite
- for (index = 0; index < mBindingCount[mode]; index++)
- {
- if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask)
- break;
- }
-
- if (index >= MAX_KEY_BINDINGS)
- {
- LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL;
- return FALSE;
- }
-
- if (mode >= MODE_COUNT)
- {
- LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
- return FALSE;
- }
-
- mBindings[mode][index].mKey = key;
- mBindings[mode][index].mMask = mask;
- mBindings[mode][index].mFunction = function;
-
- if (index == mBindingCount[mode])
- mBindingCount[mode]++;
-
- return TRUE;
-}
-
-LLViewerKeyboard::KeyBinding::KeyBinding()
-: key("key"),
- mask("mask"),
- command("command")
-{}
-
-LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode)
-: bindings("binding"),
- mode(_mode)
-{}
-
-LLViewerKeyboard::Keys::Keys()
-: first_person("first_person", KeyMode(MODE_FIRST_PERSON)),
- third_person("third_person", KeyMode(MODE_THIRD_PERSON)),
- edit("edit", KeyMode(MODE_EDIT)),
- sitting("sitting", KeyMode(MODE_SITTING)),
- edit_avatar("edit_avatar", KeyMode(MODE_EDIT_AVATAR))
-{}
-
-S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename)
-{
- S32 binding_count = 0;
- Keys keys;
- LLSimpleXUIParser parser;
-
- if (parser.readXUI(filename, keys)
- && keys.validateBlock())
- {
- binding_count += loadBindingMode(keys.first_person);
- binding_count += loadBindingMode(keys.third_person);
- binding_count += loadBindingMode(keys.edit);
- binding_count += loadBindingMode(keys.sitting);
- binding_count += loadBindingMode(keys.edit_avatar);
- }
- return binding_count;
-}
-
-S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode)
-{
- S32 binding_count = 0;
- for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(),
- end_it = keymode.bindings.end();
- it != end_it;
- ++it)
- {
- KEY key;
- MASK mask;
- LLKeyboard::keyFromString(it->key, &key);
- LLKeyboard::maskFromString(it->mask, &mask);
- bindKey(keymode.mode, key, mask, it->command);
- binding_count++;
- }
-
- return binding_count;
-}
-
-S32 LLViewerKeyboard::loadBindings(const std::string& filename)
-{
- LLFILE *fp;
- const S32 BUFFER_SIZE = 2048;
- char buffer[BUFFER_SIZE]; /* Flawfinder: ignore */
- // *NOTE: This buffer size is hard coded into scanf() below.
- char mode_string[MAX_STRING] = ""; /* Flawfinder: ignore */
- char key_string[MAX_STRING] = ""; /* Flawfinder: ignore */
- char mask_string[MAX_STRING] = ""; /* Flawfinder: ignore */
- char function_string[MAX_STRING] = ""; /* Flawfinder: ignore */
- S32 mode = MODE_THIRD_PERSON;
- KEY key = 0;
- MASK mask = 0;
- S32 tokens_read;
- S32 binding_count = 0;
- S32 line_count = 0;
-
- if(filename.empty())
- {
- LL_ERRS() << " No filename specified" << LL_ENDL;
- return 0;
- }
-
- fp = LLFile::fopen(filename, "r");
-
- if (!fp)
- {
- return 0;
- }
-
-
- while (!feof(fp))
- {
- line_count++;
- if (!fgets(buffer, BUFFER_SIZE, fp))
- break;
-
- // skip over comments, blank lines
- if (buffer[0] == '#' || buffer[0] == '\n') continue;
-
- // grab the binding strings
- tokens_read = sscanf( /* Flawfinder: ignore */
- buffer,
- "%254s %254s %254s %254s",
- mode_string,
- key_string,
- mask_string,
- function_string);
-
- if (tokens_read == EOF)
- {
- LL_INFOS() << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << LL_ENDL;
- fclose(fp);
- return 0;
- }
- else if (tokens_read < 4)
- {
- LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL;
- continue;
- }
-
- // convert mode
- if (!modeFromString(mode_string, &mode))
- {
- LL_INFOS() << "Unknown mode on line " << line_count << " of key binding file " << filename << LL_ENDL;
- LL_INFOS() << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << LL_ENDL;
- continue;
- }
-
- // convert key
- if (!LLKeyboard::keyFromString(key_string, &key))
- {
- LL_INFOS() << "Can't interpret key on line " << line_count << " of key binding file " << filename << LL_ENDL;
- continue;
- }
-
- // convert mask
- if (!LLKeyboard::maskFromString(mask_string, &mask))
- {
- LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL;
- continue;
- }
-
- // bind key
- if (bindKey(mode, key, mask, function_string))
- {
- binding_count++;
- }
- }
-
- fclose(fp);
-
- return binding_count;
-}
-
-
-EKeyboardMode LLViewerKeyboard::getMode()
-{
- if ( gAgentCamera.cameraMouselook() )
- {
- return MODE_FIRST_PERSON;
- }
- else if ( gMorphView && gMorphView->getVisible())
- {
- return MODE_EDIT_AVATAR;
- }
- else if (isAgentAvatarValid() && gAgentAvatarp->isSitting())
- {
- return MODE_SITTING;
- }
- else
- {
- return MODE_THIRD_PERSON;
- }
-}
-
-
-// Called from scanKeyboard.
-void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
-{
- S32 mode = getMode();
- // Consider keyboard scanning as NOT mouse event. JC
- MASK mask = gKeyboard->currentMask(FALSE);
-
- LLKeyBinding* binding = mBindings[mode];
- S32 binding_count = mBindingCount[mode];
-
-
- if (mKeyHandledByUI[key])
- {
- return;
- }
-
- // don't process key down on repeated keys
- BOOL repeat = gKeyboard->getKeyRepeated(key);
-
- for (S32 i = 0; i < binding_count; i++)
- {
- //for (S32 key = 0; key < KEY_COUNT; key++)
- if (binding[i].mKey == key)
- {
- //if (binding[i].mKey == key && binding[i].mMask == mask)
- if (binding[i].mMask == mask)
- {
- if (key_down && !repeat)
- {
- // ...key went down this frame, call function
- binding[i].mFunction( KEYSTATE_DOWN );
- }
- else if (key_up)
- {
- // ...key went down this frame, call function
- binding[i].mFunction( KEYSTATE_UP );
- }
- else if (key_level)
- {
- // ...key held down from previous frame
- // Not windows, just call the function.
- binding[i].mFunction( KEYSTATE_LEVEL );
- }//if
- }//if
- }//for
- }//for
-}
diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h
deleted file mode 100644
index 110dc89d28..0000000000
--- a/indra/newview/llviewerkeyboard.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * @file llviewerkeyboard.h
- * @brief LLViewerKeyboard class header file
- *
- * $LicenseInfo:firstyear=2005&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_LLVIEWERKEYBOARD_H
-#define LL_LLVIEWERKEYBOARD_H
-
-#include "llkeyboard.h" // For EKeystate
-#include "llinitparam.h"
-
-const S32 MAX_NAMED_FUNCTIONS = 100;
-const S32 MAX_KEY_BINDINGS = 128; // was 60
-
-class LLNamedFunction
-{
-public:
- LLNamedFunction() : mFunction(NULL) { };
- ~LLNamedFunction() { };
-
- std::string mName;
- LLKeyFunc mFunction;
-};
-
-typedef enum e_keyboard_mode
-{
- MODE_FIRST_PERSON,
- MODE_THIRD_PERSON,
- MODE_EDIT,
- MODE_EDIT_AVATAR,
- MODE_SITTING,
- MODE_COUNT
-} EKeyboardMode;
-
-
-void bind_keyboard_functions();
-
-class LLViewerKeyboard
-{
-public:
- struct KeyBinding : public LLInitParam::Block<KeyBinding>
- {
- Mandatory<std::string> key,
- mask,
- command;
-
- KeyBinding();
- };
-
- struct KeyMode : public LLInitParam::Block<KeyMode>
- {
- Multiple<KeyBinding> bindings;
- EKeyboardMode mode;
- KeyMode(EKeyboardMode mode);
- };
-
- struct Keys : public LLInitParam::Block<Keys>
- {
- Optional<KeyMode> first_person,
- third_person,
- edit,
- sitting,
- edit_avatar;
-
- Keys();
- };
-
- LLViewerKeyboard();
-
- BOOL handleKey(KEY key, MASK mask, BOOL repeated);
- BOOL handleKeyUp(KEY key, MASK mask);
-
- S32 loadBindings(const std::string& filename); // returns number bound, 0 on error
- S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error
- EKeyboardMode getMode();
-
- BOOL modeFromString(const std::string& string, S32 *mode); // False on failure
-
- void scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
-
-private:
- S32 loadBindingMode(const LLViewerKeyboard::KeyMode& keymode);
- BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name);
-
- // Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
- S32 mBindingCount[MODE_COUNT];
- LLKeyBinding mBindings[MODE_COUNT][MAX_KEY_BINDINGS];
-
- typedef std::map<U32, U32> key_remap_t;
- key_remap_t mRemapKeys[MODE_COUNT];
- std::set<KEY> mKeysSkippedByUI;
- BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI
-};
-
-extern LLViewerKeyboard gViewerKeyboard;
-
-#endif // LL_LLVIEWERKEYBOARD_H
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6cfc22a4e5..9ed2df2759 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -57,6 +57,7 @@
#include "llviewercontrol.h"
#include "llviewermenufile.h" // LLFilePickerThread
#include "llviewernetwork.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -193,7 +194,6 @@ static F32 sGlobalVolume = 1.0f;
static bool sForceUpdate = false;
static LLUUID sOnlyAudibleTextureID = LLUUID::null;
static F64 sLowestLoadableImplInterest = 0.0f;
-static bool sAnyMediaShowing = false;
//////////////////////////////////////////////////////////////////////////////////////////
static void add_media_impl(LLViewerMediaImpl* media)
@@ -411,7 +411,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
// Just in case we need to check browser differences in A/B test
// builds.
- std::string channel = LLVersionInfo::getChannel();
+ std::string channel = LLVersionInfo::instance().getChannel();
// append our magic version number string to the browser user agent id
// See the HTTP 1.0 and 1.1 specifications for allowed formats:
@@ -421,7 +421,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
// http://www.mozilla.org/build/revised-user-agent-strings.html
std::ostringstream codec;
codec << "SecondLife/";
- codec << LLVersionInfo::getVersion();
+ codec << LLVersionInfo::instance().getVersion();
codec << " (" << channel << "; " << skin_name << " skin)";
LL_INFOS() << codec.str() << LL_ENDL;
@@ -865,7 +865,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
if (!pimpl->getUsedInUI() && pimpl->hasMedia())
{
- sAnyMediaShowing = true;
+ mAnyMediaShowing = true;
}
if (!pimpl->getUsedInUI() && pimpl->hasMedia() && (pimpl->isMediaPlaying() || !pimpl->isMediaTimeBased()))
@@ -1018,12 +1018,14 @@ void LLViewerMedia::setAllMediaPaused(bool val)
}
}
+ LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
// Also do Parcel Media and Parcel Audio
if (!val)
{
if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia())
{
- LLViewerParcelMedia::getInstance()->play(LLViewerParcelMgr::getInstance()->getAgentParcel());
+ LLViewerParcelMedia::getInstance()->play(agent_parcel);
}
static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true);
@@ -1051,6 +1053,12 @@ void LLViewerMedia::setAllMediaPaused(bool val)
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
+
+ // remove play choice for current parcel
+ if (agent_parcel && gAgent.getRegion())
+ {
+ LLViewerParcelAskPlay::getInstance()->resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID());
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1710,23 +1718,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
user_data_path_cache += gDirUtilp->getDirDelimiter();
- std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
- user_data_path_cookies += gDirUtilp->getDirDelimiter();
-
std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
- // Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
- // If the linden username returned is blank, that can only mean we are
- // at the login page displaying login Web page or Web browser test via Develop menu.
- // In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this
- // is what we always used before this change)
- std::string linden_user_dir = gDirUtilp->getLindenUserDir();
- if ( ! linden_user_dir.empty() )
- {
- user_data_path_cookies = linden_user_dir;
- user_data_path_cookies += gDirUtilp->getDirDelimiter();
- };
-
// See if the plugin executable exists
llstat s;
if(LLFile::stat(launcher_name, &s))
@@ -1743,7 +1736,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
- media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
+ media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log);
media_source->setLanguageCode(LLUI::getLanguage());
media_source->setZoomFactor(zoom_factor);
@@ -2285,14 +2278,26 @@ void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
}
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, MASK mask)
+void LLViewerMediaImpl::scrollWheel(const LLVector2& texture_coords, S32 scroll_x, S32 scroll_y, MASK mask)
+{
+ if (mMediaSource)
+ {
+ S32 x, y;
+ scaleTextureCoords(texture_coords, &x, &y);
+
+ scrollWheel(x, y, scroll_x, scroll_y, mask);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask)
{
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
{
- mMediaSource->scrollEvent(x, y, mask);
+ mMediaSource->scrollEvent(x, y, scroll_x, scroll_y, mask);
}
}
@@ -3754,7 +3759,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
bool LLViewerMediaImpl::isAutoPlayable() const
{
return (mMediaAutoPlay &&
- gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
+ gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0 &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 014f9048f0..8bf1ad2441 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -235,7 +235,8 @@ public:
void mouseMove(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0);
- void scrollWheel(S32 x, S32 y, MASK mask);
+ void scrollWheel(const LLVector2& texture_coords, S32 scroll_x, S32 scroll_y, MASK mask);
+ void scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask);
void mouseCapture();
void navigateBack();
@@ -320,6 +321,7 @@ public:
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
+ /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index f4a64a8e55..ba80eeb6b6 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -205,8 +205,9 @@ bool LLViewerMediaFocus::getFocus()
}
// This function selects an ideal viewing distance based on the focused object, pick normal, and padding value
-void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only)
+LLVector3d LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only)
{
+ LLVector3d camera_pos;
if (object)
{
gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
@@ -254,7 +255,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
distance += depth * 0.5;
// Finally animate the camera to this new position and focal point
- LLVector3d camera_pos, target_pos;
+ LLVector3d target_pos;
// The target lookat position is the center of the selection (in global coords)
target_pos = center;
// Target look-from (camera) position is "distance" away from the target along the normal
@@ -287,7 +288,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
if (zoom_in_only &&
(dist_vec_squared(gAgentCamera.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos)))
{
- return;
+ return camera_pos;
}
gAgentCamera.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() );
@@ -298,6 +299,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
// If we have no object, focus back on the avatar.
gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
}
+ return camera_pos;
}
void LLViewerMediaFocus::onFocusReceived()
{
@@ -338,15 +340,6 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
clearFocus();
}
-
- if ( KEY_F1 == key && LLUI::getInstance()->mHelpImpl && mMediaControls.get())
- {
- std::string help_topic;
- if (mMediaControls.get()->findHelpTopic(help_topic))
- {
- LLUI::getInstance()->mHelpImpl->showTopic(help_topic);
- }
- }
}
return true;
@@ -371,18 +364,26 @@ BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
media_impl->handleUnicodeCharHere(uni_char);
return true;
}
-BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks)
+
+BOOL LLViewerMediaFocus::handleScrollWheel(const LLVector2& texture_coords, S32 clicks_x, S32 clicks_y)
+{
+ BOOL retval = FALSE;
+ LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
+ if (media_impl && media_impl->hasMedia())
+ {
+ media_impl->scrollWheel(texture_coords, clicks_x, clicks_y, gKeyboard->currentMask(TRUE));
+ retval = TRUE;
+ }
+ return retval;
+}
+
+BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks_x, S32 clicks_y)
{
BOOL retval = FALSE;
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
if(media_impl && media_impl->hasMedia())
{
- // the scrollEvent() API's x and y are not the same as handleScrollWheel's x and y.
- // The latter is the position of the mouse at the time of the event
- // The former is the 'scroll amount' in x and y, respectively.
- // All we have for 'scroll amount' here is 'clicks'.
- // We're also not passed the keyboard modifier mask, but we can get that from gKeyboard.
- media_impl->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
+ media_impl->scrollWheel(x, y, clicks_x, clicks_y, gKeyboard->currentMask(TRUE));
retval = TRUE;
}
return retval;
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index 763a6c1688..effd08a559 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -58,16 +58,18 @@ public:
/*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
/*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent);
/*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ BOOL handleScrollWheel(const LLVector2& texture_coords, S32 clicks_x, S32 clicks_y);
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks_x, S32 clicks_y);
void update();
- static void setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false);
+ static LLVector3d setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false);
static F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face);
bool isHoveringOverFace(LLPointer<LLViewerObject> objectp, S32 face);
-
+ bool isHoveringOverFocused() { return mFocusedObjectID == mHoverObjectID && mFocusedObjectFace == mHoverObjectFace; };
+
// These look up (by uuid) and return the values that were set with setFocusFace. They will return null if the objects have been destroyed.
LLViewerMediaImpl* getFocusedMediaImpl();
LLViewerObject* getFocusedObject();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8e10500efb..fbf057603e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -45,15 +45,15 @@
// newview includes
#include "llagent.h"
#include "llagentaccess.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llagentui.h"
#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llcompilequeue.h"
#include "llconsole.h"
-#include "lldaycyclemanager.h"
#include "lldebugview.h"
-#include "llenvmanager.h"
+#include "llenvironment.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloaterabout.h"
@@ -64,6 +64,7 @@
#include "llfloaterimcontainer.h"
#include "llfloaterland.h"
#include "llfloaterimnearbychat.h"
+#include "llfloaterlandholdings.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpay.h"
@@ -120,21 +121,19 @@
#include "llworldmap.h"
#include "pipeline.h"
#include "llviewerjoystick.h"
-#include "llwaterparammanager.h"
-#include "llwlanimator.h"
-#include "llwlparammanager.h"
#include "llfloatercamera.h"
#include "lluilistener.h"
#include "llappearancemgr.h"
#include "lltrans.h"
-#include "lleconomy.h"
#include "lltoolgrab.h"
#include "llwindow.h"
#include "llpathfindingmanager.h"
#include "llstartup.h"
#include "boost/unordered_map.hpp"
#include <boost/regex.hpp>
+#include <boost/algorithm/string.hpp>
#include "llcleanup.h"
+#include "llviewershadermgr.h"
using namespace LLAvatarAppearanceDefines;
@@ -187,11 +186,15 @@ const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"
LLMenuGL* gAttachSubMenu = NULL;
LLMenuGL* gDetachSubMenu = NULL;
LLMenuGL* gTakeOffClothes = NULL;
+LLMenuGL* gDetachAvatarMenu = NULL;
+LLMenuGL* gDetachHUDAvatarMenu = NULL;
LLContextMenu* gAttachScreenPieMenu = NULL;
LLContextMenu* gAttachPieMenu = NULL;
LLContextMenu* gAttachBodyPartPieMenus[9];
LLContextMenu* gDetachPieMenu = NULL;
LLContextMenu* gDetachScreenPieMenu = NULL;
+LLContextMenu* gDetachAttSelfMenu = NULL;
+LLContextMenu* gDetachHUDAttSelfMenu = NULL;
LLContextMenu* gDetachBodyPartPieMenus[9];
//
@@ -377,20 +380,6 @@ void initialize_menus();
// Break up groups of more than 6 items with separators
//-----------------------------------------------------------------------------
-void set_underclothes_menu_options()
-{
- if (gMenuHolder && gAgent.isTeen())
- {
- gMenuHolder->getChild<LLView>("Self Underpants")->setVisible(FALSE);
- gMenuHolder->getChild<LLView>("Self Undershirt")->setVisible(FALSE);
- }
- if (gMenuBarView && gAgent.isTeen())
- {
- gMenuBarView->getChild<LLView>("Menu Underpants")->setVisible(FALSE);
- gMenuBarView->getChild<LLView>("Menu Undershirt")->setVisible(FALSE);
- }
-}
-
void set_merchant_SLM_menu()
{
// All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
@@ -401,23 +390,20 @@ void set_merchant_SLM_menu()
void check_merchant_status(bool force)
{
- if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))
+ if (force)
{
- if (force)
- {
- // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
- }
- // Hide SLM related menu item
- gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
-
- // Also disable the toolbar button for Marketplace Listings
- LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
- gToolBarView->enableCommand(command->id(), false);
-
- // Launch an SLM test connection to get the merchant status
- LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
+ // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
}
+ // Hide SLM related menu item
+ gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
+
+ // Also disable the toolbar button for Marketplace Listings
+ LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
+ gToolBarView->enableCommand(command->id(), false);
+
+ // Launch an SLM test connection to get the merchant status
+ LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
}
void init_menus()
@@ -463,6 +449,9 @@ void init_menus()
gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
"menu_attachment_other.xml", gMenuHolder, registry);
+ gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true);
+ gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true);
+
gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
"menu_land.xml", gMenuHolder, registry);
@@ -508,17 +497,20 @@ void init_menus()
gViewerWindow->setMenuBackgroundColor(false,
LLGridManager::getInstance()->isInProductionGrid());
- // Assume L$10 for now, the server will tell us the real cost at login
// *TODO:Also fix cost in llfolderview.cpp for Inventory menus
- const std::string upload_cost("10");
- gMenuHolder->childSetLabelArg("Upload Image", "[COST]", upload_cost);
- gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost);
- gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
- gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
+ const std::string texture_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost());
+ const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
+ const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
+ gMenuHolder->childSetLabelArg("Upload Image", "[COST]", texture_upload_cost_str);
+ gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
+ gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
+ gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
+ gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
+
// Don't display the Memory console menu if the feature is turned off
LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE);
if (memoryMenu)
@@ -695,19 +687,6 @@ class LLAdvancedCheckHUDInfo : public view_listener_t
};
-//////////////
-// FLYING //
-//////////////
-
-class LLAdvancedAgentFlyingInfo : public view_listener_t
-{
- bool handleEvent(const LLSD&)
- {
- return gAgent.getFlying();
- }
-};
-
-
///////////////////////
// CLEAR GROUP CACHE //
///////////////////////
@@ -745,6 +724,10 @@ U32 render_type_from_string(std::string render_type)
{
return LLPipeline::RENDER_TYPE_AVATAR;
}
+ else if ("controlAV" == render_type) // Animesh
+ {
+ return LLPipeline::RENDER_TYPE_CONTROL_AV;
+ }
else if ("surfacePatch" == render_type)
{
return LLPipeline::RENDER_TYPE_TERRAIN;
@@ -2276,8 +2259,8 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
+ bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
+ LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
return new_value;
}
};
@@ -2289,8 +2272,8 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
+ 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;
}
};
@@ -2782,7 +2765,6 @@ class LLObjectBuild : public view_listener_t
}
};
-
void handle_object_edit()
{
LLViewerParcelMgr::getInstance()->deselectLand();
@@ -2827,6 +2809,57 @@ void handle_object_edit()
return;
}
+void handle_attachment_edit(const LLUUID& inv_item_id)
+{
+ if (isAgentAvatarValid())
+ {
+ if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id))
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj);
+
+ handle_object_edit();
+ }
+ }
+}
+
+void handle_attachment_touch(const LLUUID& inv_item_id)
+{
+ if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) )
+ {
+ if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)))
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+
+ LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj);
+ if (!LLToolMgr::getInstance()->inBuildMode())
+ {
+ struct SetTransient : public LLSelectedNodeFunctor
+ {
+ bool apply(LLSelectNode* node)
+ {
+ node->setTransient(TRUE);
+ return true;
+ }
+ } f;
+ sel->applyToNodes(&f);
+ }
+
+ handle_object_touch();
+ }
+ }
+}
+
+bool enable_attachment_touch(const LLUUID& inv_item_id)
+{
+ if (isAgentAvatarValid())
+ {
+ const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
+ return (attach_obj) && (attach_obj->flagHandleTouch());
+ }
+ return false;
+}
+
void handle_object_inspect()
{
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
@@ -3149,6 +3182,7 @@ class LLObjectMute : public view_listener_t
if (avatar)
{
avatar->mNeedsImpostorUpdate = TRUE;
+ avatar->mLastImpostorUpdateReason = 9;
id = avatar->getID();
@@ -3707,6 +3741,35 @@ bool enable_sitdown_self()
return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
}
+class LLSelfToggleSitStand : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (isAgentAvatarValid())
+ {
+ if (gAgentAvatarp->isSitting())
+ {
+ gAgent.standUp();
+ }
+ else
+ {
+ gAgent.sitDown();
+ }
+ }
+ return true;
+ }
+};
+
+bool enable_sit_stand()
+{
+ return enable_sitdown_self() || enable_standup_self();
+}
+
+bool enable_fly_land()
+{
+ return gAgent.getFlying() || LLAgent::enableFlying();
+}
+
class LLCheckPanelPeopleTab : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -4109,8 +4172,7 @@ void handle_reset_view()
// switching to outfit selector should automagically save any currently edited wearable
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
}
-
- gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
+ gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE);
reset_view_final( TRUE );
LLFloaterCamera::resetCameraMode();
}
@@ -4601,6 +4663,18 @@ void handle_take_copy()
derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
}
+void handle_link_objects()
+{
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ LLFloaterReg::toggleInstanceOrBringToFront("places");
+ }
+ else
+ {
+ LLSelectMgr::getInstance()->linkObjects();
+ }
+}
+
// You can return an object to its owner if it is on your land.
class LLObjectReturn : public view_listener_t
{
@@ -4897,7 +4971,7 @@ void handle_buy_or_take()
{
LLStringUtil::format_map_t args;
args["AMOUNT"] = llformat("%d", total_price);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "BuyingCosts", args ), total_price );
+ LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );
}
}
else
@@ -4926,13 +5000,6 @@ bool tools_visible_take_object()
return !is_selection_buy_not_take();
}
-bool enable_how_to_visible(const LLSD& param)
-{
- LLFloaterWebContent::Params p;
- p.target = "__help_how_to";
- return LLFloaterReg::instanceVisible("how_to", p);
-}
-
class LLToolsEnableBuyOrTake : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -5359,7 +5426,7 @@ class LLToolsSelectNextPartFace : public view_listener_t
new_te = to_select->getNumTEs() - 1;
}
}
- LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE);
+ LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);
}
else
{
@@ -5888,6 +5955,16 @@ class LLWorldSetHomeLocation : public view_listener_t
}
};
+class LLWorldLindenHome : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url");
+ LLWeb::loadURL(url);
+ return true;
+ }
+};
+
class LLWorldTeleportHome : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -5970,7 +6047,7 @@ class LLWorldCreateLandmark : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+ LLFloaterReg::showInstance("add_landmark");
return true;
}
@@ -6301,6 +6378,11 @@ void handle_edit_outfit()
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
}
+void handle_now_wearing()
+{
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "now_wearing"));
+}
+
void handle_edit_shape()
{
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
@@ -7083,7 +7165,21 @@ BOOL object_is_wearable()
{
return FALSE;
}
- return gAgentAvatarp->canAttachMoreObjects();
+ if (!gAgentAvatarp->canAttachMoreObjects())
+ {
+ return FALSE;
+ }
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ if (node->mPermissions->getOwner() == gAgent.getID())
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
@@ -7381,6 +7477,8 @@ void handle_dump_attachments(void*)
// these are used in the gl menus to set control values, generically.
class LLToggleControl : public view_listener_t
{
+protected:
+
bool handleEvent(const LLSD& userdata)
{
std::string control_name = userdata.asString();
@@ -7457,6 +7555,24 @@ class LLAdvancedClickRenderBenchmark: public view_listener_t
}
};
+// these are used in the gl menus to set control values that require shader recompilation
+class LLToggleShaderControl : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string control_name = userdata.asString();
+ BOOL checked = gSavedSettings.getBOOL( control_name );
+ gSavedSettings.setBOOL( control_name, !checked );
+ LLPipeline::refreshCachedSettings();
+ //gPipeline.updateRenderDeferred();
+ //gPipeline.releaseGLBuffers();
+ //gPipeline.createGLBuffers();
+ //gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ return !checked;
+ }
+};
+
void menu_toggle_attached_lights(void* user_data)
{
LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
@@ -7623,15 +7739,7 @@ class LLToggleHowTo : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLFloaterWebContent::Params p;
- std::string url = gSavedSettings.getString("HowToHelpURL");
- p.url = LLWeb::expandURLSubstitutions(url, LLSD());
- p.show_chrome = false;
- p.target = "__help_how_to";
- p.show_page_title = false;
- p.preferred_media_size = LLRect(0, 460, 335, 0);
-
- LLFloaterReg::toggleInstanceOrBringToFront("how_to", p);
+ LLFloaterReg::toggleInstanceOrBringToFront("guidebook");
return true;
}
};
@@ -7830,7 +7938,7 @@ void handle_grab_baked_texture(void* data)
if(folder_id.notNull())
{
std::string name;
- name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+ name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
LLUUID item_id;
item_id.generate();
@@ -8003,7 +8111,6 @@ BOOL LLViewerMenuHolderGL::hideMenus()
if (LLMenuHolderGL::hideMenus())
{
- LLToolPie::instance().blockClickToWalk();
handled = TRUE;
}
@@ -8258,6 +8365,14 @@ class LLViewToggleBeacon : public view_listener_t
gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
}
}
+ else if (beacon == "sunbeacon")
+ {
+ gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon"));
+ }
+ else if (beacon == "moonbeacon")
+ {
+ gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon"));
+ }
else if (beacon == "renderbeacons")
{
LLPipeline::toggleRenderBeacons();
@@ -8474,42 +8589,68 @@ class LLToolsSelectTool : public view_listener_t
/// WINDLIGHT callbacks
class LLWorldEnvSettings : public view_listener_t
{
+ void defocusEnvFloaters()
+ {
+ //currently there is only one instance of each floater
+ std::vector<std::string> env_floaters_names = { "env_edit_extdaycycle", "env_fixed_environmentent_water", "env_fixed_environmentent_sky" };
+ for (std::vector<std::string>::const_iterator it = env_floaters_names.begin(); it != env_floaters_names.end(); ++it)
+ {
+ LLFloater* env_floater = LLFloaterReg::findTypedInstance<LLFloater>(*it);
+ if (env_floater)
+ {
+ env_floater->setFocus(FALSE);
+ }
+ }
+ }
+
bool handleEvent(const LLSD& userdata)
{
- std::string tod = userdata.asString();
+ std::string event_name = userdata.asString();
- if (tod == "editor")
+ if (event_name == "sunrise")
{
- LLFloaterReg::toggleInstance("env_settings");
- return true;
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
}
-
- if (tod == "sunrise")
+ else if (event_name == "noon")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Sunrise");
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
}
- else if (tod == "noon")
+ else if (event_name == "sunset")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Midday");
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
}
- else if (tod == "sunset")
+ else if (event_name == "midnight")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Sunset");
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
}
- else if (tod == "midnight")
+ else if (event_name == "region")
{
- LLEnvManagerNew::instance().setUseSkyPreset("Midnight");
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
}
+ else if (event_name == "pause_clouds")
+ {
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ LLEnvironment::instance().resumeCloudScroll();
else
+ LLEnvironment::instance().pauseCloudScroll();
+ }
+ else if (event_name == "adjust_tool")
{
- LLEnvManagerNew &envmgr = LLEnvManagerNew::instance();
- // reset all environmental settings to track the region defaults, make this reset 'sticky' like the other sun settings.
- bool use_fixed_sky = false;
- bool use_region_settings = true;
- envmgr.setUserPrefs(envmgr.getWaterPresetName(),
- envmgr.getSkyPresetName(),
- envmgr.getDayCycleName(),
- use_fixed_sky, use_region_settings);
+ LLFloaterReg::showInstance("env_adjust_snapshot");
+ }
+ else if (event_name == "my_environs")
+ {
+ LLFloaterReg::showInstance("my_environments");
}
return true;
@@ -8521,39 +8662,46 @@ class LLWorldEnableEnvSettings : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
bool result = false;
- std::string tod = userdata.asString();
+ std::string event_name = userdata.asString();
- if (LLEnvManagerNew::instance().getUseRegionSettings())
+ if (event_name == "pause_clouds")
{
- return (tod == "region");
+ return LLEnvironment::instance().isCloudScrollPaused();
}
- if (LLEnvManagerNew::instance().getUseFixedSky())
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
+
+ if (!sky)
{
- if (tod == "sunrise")
+ return (event_name == "region");
+ }
+
+ std::string skyname = (sky) ? sky->getName() : "";
+ LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
+
+ if (event_name == "sunrise")
{
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunrise");
+ result = (skyid == LLEnvironment::KNOWN_SKY_SUNRISE);
}
- else if (tod == "noon")
+ else if (event_name == "noon")
{
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midday");
+ result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY);
}
- else if (tod == "sunset")
+ else if (event_name == "sunset")
{
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Sunset");
+ result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET);
}
- else if (tod == "midnight")
+ else if (event_name == "midnight")
{
- result = (LLEnvManagerNew::instance().getSkyPresetName() == "Midnight");
+ result = (skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT);
}
- else if (tod == "region")
+ else if (event_name == "region")
{
return false;
}
else
{
- LL_WARNS() << "Unknown time-of-day item: " << tod << LL_ENDL;
- }
+ LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL;
}
return result;
}
@@ -8567,39 +8715,27 @@ class LLWorldEnvPreset : public view_listener_t
if (item == "new_water")
{
- LLFloaterReg::showInstance("env_edit_water", "new");
+ LLFloaterReg::showInstance("env_fixed_environmentent_water", "new");
}
else if (item == "edit_water")
{
- LLFloaterReg::showInstance("env_edit_water", "edit");
- }
- else if (item == "delete_water")
- {
- LLFloaterReg::showInstance("env_delete_preset", "water");
+ LLFloaterReg::showInstance("env_fixed_environmentent_water", "edit");
}
else if (item == "new_sky")
{
- LLFloaterReg::showInstance("env_edit_sky", "new");
+ LLFloaterReg::showInstance("env_fixed_environmentent_sky", "new");
}
else if (item == "edit_sky")
{
- LLFloaterReg::showInstance("env_edit_sky", "edit");
- }
- else if (item == "delete_sky")
- {
- LLFloaterReg::showInstance("env_delete_preset", "sky");
+ LLFloaterReg::showInstance("env_fixed_environmentent_sky", "edit");
}
else if (item == "new_day_cycle")
{
- LLFloaterReg::showInstance("env_edit_day_cycle", "new");
+ LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
}
else if (item == "edit_day_cycle")
{
- LLFloaterReg::showInstance("env_edit_day_cycle", "edit");
- }
- else if (item == "delete_day_cycle")
- {
- LLFloaterReg::showInstance("env_delete_preset", "day_cycle");
+ LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
}
else
{
@@ -8614,30 +8750,6 @@ class LLWorldEnableEnvPreset : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- std::string item = userdata.asString();
-
- if (item == "delete_water")
- {
- LLWaterParamManager::preset_name_list_t user_waters;
- LLWaterParamManager::instance().getUserPresetNames(user_waters);
- return !user_waters.empty();
- }
- else if (item == "delete_sky")
- {
- LLWLParamManager::preset_name_list_t user_skies;
- LLWLParamManager::instance().getUserPresetNames(user_skies);
- return !user_skies.empty();
- }
- else if (item == "delete_day_cycle")
- {
- LLDayCycleManager::preset_name_list_t user_days;
- LLDayCycleManager::instance().getUserPresetNames(user_days);
- return !user_days.empty();
- }
- else
- {
- LL_WARNS() << "Unknown item" << LL_ENDL;
- }
return false;
}
@@ -8665,18 +8777,42 @@ class LLUploadCostCalculator : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
- std::string menu_name = userdata.asString();
+ std::vector<std::string> fields;
+ std::string str = userdata.asString();
+ boost::split(fields, str, boost::is_any_of(","));
+ if (fields.size()<1)
+ {
+ return false;
+ }
+ std::string menu_name = fields[0];
+ std::string asset_type_str = "texture";
+ if (fields.size()>1)
+ {
+ asset_type_str = fields[1];
+ }
+ LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL;
+ calculateCost(asset_type_str);
gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);
return true;
}
- void calculateCost();
+ void calculateCost(const std::string& asset_type_str);
public:
LLUploadCostCalculator()
{
- calculateCost();
+ }
+};
+
+class LLUpdateMembershipLabel : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText");
+ gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str);
+
+ return true;
}
};
@@ -8702,19 +8838,27 @@ class LLToggleUIHints : public view_listener_t
}
};
-void LLUploadCostCalculator::calculateCost()
+void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str)
{
- S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ S32 upload_cost = -1;
- // getPriceUpload() returns -1 if no data available yet.
- if(upload_cost >= 0)
+ if (asset_type_str == "texture")
{
- mCostStr = llformat("%d", upload_cost);
+ upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
}
- else
+ else if (asset_type_str == "animation")
{
- mCostStr = llformat("%d", gSavedSettings.getU32("DefaultUploadCost"));
+ upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
}
+ else if (asset_type_str == "sound")
+ {
+ upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost();
+ }
+ if (upload_cost < 0)
+ {
+ LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL;
+ }
+ mCostStr = std::to_string(upload_cost);
}
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
@@ -8821,11 +8965,13 @@ void initialize_menus()
view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
+ view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel");
+
enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
// Agent
commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
- enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying));
+ enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));
commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));
commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));
commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
@@ -8841,6 +8987,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
+ commit.add("NowWearing", boost::bind(&handle_now_wearing));
commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
commit.add("EditShape", boost::bind(&handle_edit_shape));
commit.add("HoverHeight", boost::bind(&handle_hover_height));
@@ -8873,9 +9020,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
- // Me > Movement
- view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
-
//Communicate Nearby chat
view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
@@ -8897,6 +9041,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
+ view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");
view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
@@ -8922,7 +9067,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart");
- commit.add("Tools.Link", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
+ commit.add("Tools.Link", boost::bind(&handle_link_objects));
commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
@@ -8951,7 +9096,6 @@ void initialize_menus()
// Help menu
// most items use the ShowFloater method
view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
- enable.add("Help.HowToVisible", boost::bind(&enable_how_to_visible, _2));
// Advanced menu
view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
@@ -9139,11 +9283,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
// Self context menu
- view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
- enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self));
- view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown");
- enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
- enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self));
+ view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand");
+ enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));
view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
@@ -9209,6 +9350,7 @@ void initialize_menus()
enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
+ enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
@@ -9248,6 +9390,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
+ view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
view_listener_t::addMenu(new LLCheckControl(), "CheckControl");
view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
commit.add("PayObject", boost::bind(&handle_give_money_dialog));
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 6882405407..36b6971c81 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -82,7 +82,6 @@ void handle_detach(void*);
BOOL enable_god_full(void* user_data);
BOOL enable_god_liaison(void* user_data);
BOOL enable_god_basic(void* user_data);
-void set_underclothes_menu_options();
void check_merchant_status(bool force = false);
void exchange_callingcard(const LLUUID& dest_id);
@@ -110,6 +109,10 @@ void handle_object_return();
void handle_object_delete();
void handle_object_edit();
+void handle_attachment_edit(const LLUUID& inv_item_id);
+void handle_attachment_touch(const LLUUID& inv_item_id);
+bool enable_attachment_touch(const LLUUID& inv_item_id);
+
void handle_buy_land();
// Takes avatar UUID, or if no UUID passed, uses last selected object
@@ -185,10 +188,14 @@ extern LLContextMenu *gMenuMuteParticle;
extern LLMenuGL* gAttachSubMenu;
extern LLMenuGL* gDetachSubMenu;
extern LLMenuGL* gTakeOffClothes;
+extern LLMenuGL* gDetachAvatarMenu;
+extern LLMenuGL* gDetachHUDAvatarMenu;
extern LLContextMenu* gAttachScreenPieMenu;
extern LLContextMenu* gDetachScreenPieMenu;
+extern LLContextMenu* gDetachHUDAttSelfMenu;
extern LLContextMenu* gAttachPieMenu;
extern LLContextMenu* gDetachPieMenu;
+extern LLContextMenu* gDetachAttSelfMenu;
extern LLContextMenu* gAttachBodyPartPieMenus[9];
extern LLContextMenu* gDetachBodyPartPieMenus[9];
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index a9a91b158b..15181dcd9f 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -30,6 +30,7 @@
// project includes
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llfilepicker.h"
#include "llfloaterreg.h"
@@ -67,7 +68,6 @@
#include "llviewerassetupload.h"
// linden libraries
-#include "lleconomy.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llsdutil.h"
@@ -85,8 +85,6 @@ class LLFileEnableUpload : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
return true;
-// bool new_value = gStatusBar && LLGlobalEconomy::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::getInstance()->getPriceUpload());
-// return new_value;
}
};
@@ -393,7 +391,9 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP
}
if (type == LLFilePicker::FFLOAD_ANIM)
{
- if (filename.rfind(".anim") != std::string::npos)
+ std::string filename_lc(filename);
+ LLStringUtil::toLower(filename_lc);
+ if (filename_lc.rfind(".anim") != std::string::npos)
{
LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
}
@@ -406,22 +406,18 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP
return;
}
-
-const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification, const LLSD& response)
{
- // TODO:
- // Check user balance for entire cost
- // Charge user entire cost
- // Loop, uploading
- // If an upload fails, refund the user for that one
- //
- // Also fix single upload to charge first, then refund
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0)
+ {
+ // Cancel upload
+ return;
+ }
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
{
std::string filename = (*in_iter);
- if (!check_file_extension(filename, type)) continue;
std::string name = gDirUtilp->getBaseFileName(filename, true);
std::string asset_name = name;
@@ -430,6 +426,13 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::
LLStringUtil::stripNonprintable(asset_name);
LLStringUtil::trim(asset_name);
+ std::string ext = gDirUtilp->getExtension(filename);
+ LLAssetType::EType asset_type;
+ U32 codec;
+ S32 expected_upload_cost;
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
+ LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
+ {
LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
filename,
asset_name,
@@ -440,9 +443,96 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::
LLFloaterPerms::getEveryonePerms("Uploads"),
expected_upload_cost));
- upload_new_resource(uploadInfo, NULL, NULL);
+ upload_new_resource(uploadInfo);
}
}
+}
+
+bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S32& total_cost, S32& file_count, S32& bvh_count)
+{
+ total_cost = 0;
+ file_count = 0;
+ bvh_count = 0;
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ std::string filename = (*in_iter);
+ std::string ext = gDirUtilp->getExtension(filename);
+
+ if (ext == "bvh")
+ {
+ bvh_count++;
+ }
+
+ LLAssetType::EType asset_type;
+ U32 codec;
+ S32 cost;
+
+ if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
+ LLAgentBenefitsMgr::current().findUploadCost(asset_type, cost))
+ {
+ total_cost += cost;
+ file_count++;
+ }
+ }
+
+ return file_count > 0;
+}
+
+const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+{
+ // TODO:
+ // Check user balance for entire cost
+ // Charge user entire cost
+ // Loop, uploading
+ // If an upload fails, refund the user for that one
+ //
+ // Also fix single upload to charge first, then refund
+
+ // FIXME PREMIUM what about known types that can't be bulk uploaded
+ // (bvh)? These will fail in the item by item upload but won't be
+ // mentioned in the notification.
+ std::vector<std::string> filtered_filenames;
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ const std::string& filename = *in_iter;
+ if (check_file_extension(filename, type))
+ {
+ filtered_filenames.push_back(filename);
+ }
+ }
+
+ S32 expected_upload_cost;
+ S32 expected_upload_count;
+ S32 bvh_count;
+ if (get_bulk_upload_expected_cost(filtered_filenames, expected_upload_cost, expected_upload_count, bvh_count))
+ {
+ LLSD args;
+ args["COST"] = expected_upload_cost;
+ args["COUNT"] = expected_upload_count;
+ LLNotificationsUtil::add("BulkUploadCostConfirmation", args, LLSD(), boost::bind(do_bulk_upload, filtered_filenames, _1, _2));
+
+ if (filtered_filenames.size() > expected_upload_count)
+ {
+ if (bvh_count == filtered_filenames.size() - expected_upload_count)
+ {
+ LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
+ }
+ else
+ {
+ LLNotificationsUtil::add("BulkUploadIncompatibleFiles");
+ }
+ }
+ }
+ else if (bvh_count == filtered_filenames.size())
+ {
+ LLNotificationsUtil::add("DoNotSupportBulkAnimationUpload");
+ }
+ else
+ {
+ LLNotificationsUtil::add("BulkUploadNoCompatibleFiles");
+ }
+
+}
class LLFileUploadImage : public view_listener_t
{
@@ -464,7 +554,7 @@ class LLFileUploadModel : public view_listener_t
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::getInstance("upload_model");
if (fmp && !fmp->isModelLoading())
{
- fmp->loadModel(3);
+ fmp->loadHighLodModel();
}
return TRUE;
@@ -595,10 +685,17 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
S32 width = gViewerWindow->getWindowWidthRaw();
S32 height = gViewerWindow->getWindowHeightRaw();
- if (gSavedSettings.getBOOL("HighResSnapshot"))
+ bool render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
+ bool render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
+
+ BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
+ if (high_res)
{
width *= 2;
height *= 2;
+ // not compatible with UI/HUD
+ render_ui = false;
+ render_hud = false;
}
if (gViewerWindow->rawSnapshot(raw,
@@ -606,8 +703,11 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
height,
TRUE,
FALSE,
- gSavedSettings.getBOOL("RenderUIInSnapshot"),
- FALSE))
+ render_ui,
+ render_hud,
+ FALSE,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
{
LLPointer<LLImageFormatted> formatted;
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
@@ -693,7 +793,7 @@ LLUUID upload_new_resource(
bool show_inventory)
{
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewFileResourceUploadInfo>(
src_filename,
name, desc, compression_info,
destination_folder_type, inv_type,
@@ -730,10 +830,7 @@ void upload_done_callback(
if(!(can_afford_transaction(expected_upload_cost)))
{
- LLStringUtil::format_map_t args;
- args["NAME"] = data->mAssetInfo.getName();
- args["AMOUNT"] = llformat("%d", expected_upload_cost);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost );
+ LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost );
is_balance_sufficient = FALSE;
}
else if(region)
@@ -776,7 +873,7 @@ void upload_done_callback(
create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
- data->mInventoryType, NOT_WEARABLE, next_owner_perms,
+ data->mInventoryType, NO_INV_SUBTYPE, next_owner_perms,
LLPointer<LLInventoryCallback>(NULL));
}
else
@@ -812,7 +909,7 @@ void upload_done_callback(
LLStringUtil::trim(asset_name);
std::string display_name = LLStringUtil::null;
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
+ LLAssetStorage::LLStoreAssetCallback callback;
void *userdata = NULL;
upload_new_resource(
next_file,
@@ -867,10 +964,7 @@ void upload_new_resource(
if (balance < uploadInfo->getExpectedUploadCost())
{
// insufficient funds, bail on this upload
- LLStringUtil::format_map_t args;
- args["NAME"] = uploadInfo->getName();
- args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost());
- LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost());
+ LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost());
return;
}
}
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 4e8348b5e5..4e6250d9b4 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -60,7 +60,7 @@ LLUUID upload_new_resource(
void upload_new_resource(
LLResourceUploadInfo::ptr_t &uploadInfo,
- LLAssetStorage::LLStoreAssetCallback callback = NULL,
+ LLAssetStorage::LLStoreAssetCallback callback = LLAssetStorage::LLStoreAssetCallback(),
void *userdata = NULL);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index fe67182bc4..39c891c9c1 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -32,7 +32,6 @@
#include "llaudioengine.h"
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO HACK
-#include "lleconomy.h"
#include "lleventtimer.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
@@ -51,6 +50,7 @@
#include "mean_collision_data.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llcallingcard.h"
#include "llbuycurrencyhtml.h"
@@ -116,7 +116,6 @@
#include "llviewerregion.h"
#include "llfloaterregionrestarting.h"
-#include <boost/algorithm/string/split.hpp> //
#include <boost/foreach.hpp>
#include "llnotificationmanager.h" //
@@ -374,6 +373,11 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
LL_INFOS("Messaging") << "give_money(" << uuid << "," << amount << ")"<< LL_ENDL;
if(can_afford_transaction(amount))
{
+ if (uuid.isNull())
+ {
+ LL_WARNS() << "Failed to send L$ gift to to Null UUID." << LL_ENDL;
+ return;
+ }
// gStatusBar->debitBalance(amount);
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_MoneyTransferRequest);
@@ -401,6 +405,7 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
void send_complete_agent_movement(const LLHost& sim_host)
{
+ LL_DEBUGS("Teleport", "Messaging") << "Sending CompleteAgentMovement to sim_host " << sim_host << LL_ENDL;
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_CompleteAgentMovement);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -772,7 +777,6 @@ void response_group_invitation_coro(std::string url, LLUUID group_id, bool notif
LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL;
if (notify_and_update)
{
- LLNotificationsUtil::add("JoinGroupSuccess");
gAgent.sendAgentDataUpdateRequest();
LLGroupMgr::getInstance()->clearGroupData(group_id);
@@ -903,7 +907,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
if(option == 0 && !group_id.isNull())
{
// check for promotion or demotion.
- S32 max_groups = gMaxAgentGroups;
+ S32 max_groups = LLAgentBenefitsMgr::current().getGroupMembershipLimit();
if(gAgent.isInGroup(group_id)) ++max_groups;
if(gAgent.mGroups.size() < max_groups)
@@ -2215,8 +2219,12 @@ protected:
}
};
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM");
+
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM);
+
LLUUID from_id;
BOOL from_group;
LLUUID to_id;
@@ -2868,12 +2876,12 @@ BOOL LLPostTeleportNotifiers::tick()
// We're going to pretend to be a new agent
void process_teleport_finish(LLMessageSystem* msg, void**)
{
- LL_DEBUGS("Messaging") << "Got teleport location message" << LL_ENDL;
+ LL_DEBUGS("Teleport","Messaging") << "Received TeleportFinish message" << LL_ENDL;
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
if (agent_id != gAgent.getID())
{
- LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+ LL_WARNS("Teleport","Messaging") << "Got teleport notification for wrong agent " << agent_id << " expected " << gAgent.getID() << ", ignoring!" << LL_ENDL;
return;
}
@@ -2883,12 +2891,13 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
{
// Server either ignored teleport cancel message or did not receive it in time.
// This message can't be ignored since teleport is complete at server side
+ LL_INFOS("Teleport") << "Restoring canceled teleport request" << LL_ENDL;
gAgent.restoreCanceledTeleportRequest();
}
else
{
// Race condition? Make sure all variables are set correctly for teleport to work
- LL_WARNS("Messaging") << "Teleport 'finish' message without 'start'" << LL_ENDL;
+ LL_WARNS("Teleport","Messaging") << "Teleport 'finish' message without 'start'. Setting state to TELEPORT_REQUESTED" << LL_ENDL;
gTeleportDisplay = TRUE;
LLViewerMessage::getInstance()->mTeleportStartedSignal();
gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
@@ -2897,7 +2906,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
}
else if (gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING)
{
- LL_WARNS("Messaging") << "Teleport message in the middle of other teleport" << LL_ENDL;
+ LL_WARNS("Teleport","Messaging") << "Teleport message in the middle of other teleport" << LL_ENDL;
}
// Teleport is finished; it can't be cancelled now.
@@ -2925,11 +2934,18 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle);
U32 teleport_flags;
msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
-
-
+
std::string seedCap;
msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap);
+ LL_DEBUGS("Teleport") << "TeleportFinish message params are:"
+ << " sim_ip " << sim_ip
+ << " sim_port " << sim_port
+ << " region_handle " << region_handle
+ << " teleport_flags " << teleport_flags
+ << " seedCap " << seedCap
+ << LL_ENDL;
+
// update home location if we are teleporting out of prelude - specific to teleporting to welcome area
if((teleport_flags & TELEPORT_FLAGS_SET_HOME_TO_TARGET)
&& (!gAgent.isGodlike()))
@@ -2971,7 +2987,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
gAgent.standUp();
// now, use the circuit info to tell simulator about us!
- LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
+ LL_INFOS("Teleport","Messaging") << "process_teleport_finish() sending UseCircuitCode to enable sim_host "
<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
msg->newMessageFast(_PREHASH_UseCircuitCode);
msg->nextBlockFast(_PREHASH_CircuitCode);
@@ -2980,11 +2996,12 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
msg->sendReliable(sim_host);
+ LL_INFOS("Teleport") << "Calling send_complete_agent_movement() and setting state to TELEPORT_MOVING" << LL_ENDL;
send_complete_agent_movement(sim_host);
gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
- LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from process_teleport_finish(). Seed cap == "
+ LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability(). Seed cap == "
<< seedCap << LL_ENDL;
regionp->setSeedCapability(seedCap);
@@ -3017,6 +3034,8 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
+ LL_INFOS("Teleport","Messaging") << "Received ProcessAgentMovementComplete" << LL_ENDL;
+
gShiftFrame = true;
gAgentMovementCompleted = true;
@@ -3026,13 +3045,13 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
{
- LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
- << LL_ENDL;
+ LL_WARNS("Teleport", "Messaging") << "Incorrect agent or session id in process_agent_movement_complete()"
+ << " agent " << agent_id << " expected " << gAgent.getID()
+ << " session " << session_id << " expected " << gAgent.getSessionID()
+ << ", ignoring" << LL_ENDL;
return;
}
- LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
-
// *TODO: check timestamp to make sure the movement compleation
// makes sense.
LLVector3 agent_pos;
@@ -3049,7 +3068,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
// Could happen if you were immediately god-teleported away on login,
// maybe other cases. Continue, but warn.
- LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
+ LL_WARNS("Teleport", "Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
}
F32 x, y;
@@ -3059,19 +3078,21 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
if (gAgent.getRegion())
{
- LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
+ LL_WARNS("Teleport", "Messaging") << "current region origin "
+ << gAgent.getRegion()->getOriginGlobal() << " id " << gAgent.getRegion()->getRegionID() << LL_ENDL;
}
- LL_WARNS("Messaging") << "Agent being sent to invalid home region: "
- << x << ":" << y
- << " current pos " << gAgent.getPositionGlobal()
- << LL_ENDL;
+ LL_WARNS("Teleport", "Messaging") << "Agent being sent to invalid home region: "
+ << x << ":" << y
+ << " current pos " << gAgent.getPositionGlobal()
+ << ", calling forceDisconnect()"
+ << LL_ENDL;
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("SentToInvalidRegion"));
return;
}
- LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
+ LL_INFOS("Teleport","Messaging") << "Changing home region to region id " << regionp->getRegionID() << " handle " << region_handle << " == x,y " << x << "," << y << LL_ENDL;
// set our upstream host the new simulator and shuffle things as
// appropriate.
@@ -3099,6 +3120,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
gAgentCamera.slamLookAt(look_at);
gAgentCamera.updateCamera();
+ LL_INFOS("Teleport") << "Agent movement complete, setting state to TELEPORT_START_ARRIVAL" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
if (isAgentAvatarValid())
@@ -3112,6 +3134,8 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
else
{
// This is initial log-in or a region crossing
+ LL_INFOS("Teleport") << "State is not TELEPORT_MOVING, so this is initial log-in or region crossing. "
+ << "Setting state to TELEPORT_NONE" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
if(LLStartUp::getStartupState() < STATE_STARTED)
@@ -3742,6 +3766,7 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
{
LLVector3 sun_direction;
+ LLVector3 moon_direction;
LLVector3 sun_ang_velocity;
F32 phase;
U64 space_time_usec;
@@ -3763,12 +3788,10 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
LL_DEBUGS("WindlightSync") << "Sun phase: " << phase << " rad = " << fmodf(phase / F_TWO_PI + 0.25, 1.f) * 24.f << " h" << LL_ENDL;
- gSky.setSunPhase(phase);
- gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
- if ( !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()) )
- {
- gSky.setSunDirection(sun_direction, sun_ang_velocity);
- }
+ /* LAPRAS
+ We decode these parts of the message but ignore them
+ as the real values are provided elsewhere. */
+ (void)sun_direction, (void)moon_direction, (void)phase;
}
void process_sound_trigger(LLMessageSystem *msg, void **)
@@ -5033,6 +5056,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
// notification was specified using the new mechanism, so we can just handle it here
std::string notificationID;
msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+
+ //SL-13824 skip notification when both joining a group and leaving a group
+ //remove this after server stops sending these messages
+ if (notificationID == "JoinGroupSuccess" ||
+ notificationID == "GroupDepart")
+ {
+ return true;
+ }
+
if (!LLNotifications::getInstance()->templateExists(notificationID))
{
return false;
@@ -5098,7 +5130,14 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
std::string snap_filename = gDirUtilp->getLindenUserDir();
snap_filename += gDirUtilp->getDirDelimiter();
snap_filename += LLStartUp::getScreenHomeFilename();
- gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE, LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
+ gViewerWindow->saveSnapshot(snap_filename,
+ gViewerWindow->getWindowWidthRaw(),
+ gViewerWindow->getWindowHeightRaw(),
+ FALSE, //UI
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
+ FALSE,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
}
if (notificationID == "RegionRestartMinutes" ||
@@ -5196,7 +5235,14 @@ static void process_special_alert_messages(const std::string & message)
std::string snap_filename = gDirUtilp->getLindenUserDir();
snap_filename += gDirUtilp->getDirDelimiter();
snap_filename += LLStartUp::getScreenHomeFilename();
- gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE, LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
+ gViewerWindow->saveSnapshot(snap_filename,
+ gViewerWindow->getWindowWidthRaw(),
+ gViewerWindow->getWindowHeightRaw(),
+ FALSE,
+ gSavedSettings.getBOOL("RenderHUDInSnapshot"),
+ FALSE,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
}
}
@@ -5440,16 +5486,7 @@ void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
// do some extra stuff once we get our economy data
void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
{
- LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::getInstance());
-
- S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
-
- LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
-
- gMenuHolder->getChild<LLUICtrl>("Upload Image")->setLabelArg("[COST]", llformat("%d", upload_cost));
- gMenuHolder->getChild<LLUICtrl>("Upload Sound")->setLabelArg("[COST]", llformat("%d", upload_cost));
- gMenuHolder->getChild<LLUICtrl>("Upload Animation")->setLabelArg("[COST]", llformat("%d", upload_cost));
- gMenuHolder->getChild<LLUICtrl>("Bulk Upload")->setLabelArg("[COST]", llformat("%d", upload_cost));
+ LL_DEBUGS("Benefits") << "Received economy data, not currently used" << LL_ENDL;
}
void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
@@ -5706,8 +5743,9 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
// so we'll reuse the same namespace for both throttle types.
std::string throttle_name = owner_name;
std::string self_name;
- LLAgentUI::buildFullname( self_name );
- if( owner_name == self_name )
+ LLAgentUI::buildFullname( self_name ); // does not include ' Resident'
+ std::string clean_owner_name = LLCacheName::cleanFullName(owner_name); // removes ' Resident'
+ if( clean_owner_name == self_name )
{
throttle_name = taskid.getString();
}
@@ -5742,7 +5780,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
S32 count = 0;
LLSD args;
args["OBJECTNAME"] = object_name;
- args["NAME"] = LLCacheName::cleanFullName(owner_name);
+ args["NAME"] = clean_owner_name;
S32 known_questions = 0;
bool has_not_only_debit = questions ^ SCRIPT_PERMISSIONS[SCRIPT_PERMISSION_DEBIT].permbit;
// check the received permission flags against each permission
@@ -5942,6 +5980,8 @@ std::string formatted_time(const time_t& the_time)
void process_teleport_failed(LLMessageSystem *msg, void**)
{
+ LL_WARNS("Teleport","Messaging") << "Received TeleportFailed message" << LL_ENDL;
+
std::string message_id; // Tag from server, like "RegionEntryAccessBlocked"
std::string big_reason; // Actual message to display
LLSD args;
@@ -5960,6 +6000,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
// Nothing found in the map - use what the server returned in the original message block
msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, big_reason);
}
+ LL_WARNS("Teleport") << "AlertInfo message_id " << message_id << " reason: " << big_reason << LL_ENDL;
LLSD llsd_block;
std::string llsd_raw;
@@ -5969,10 +6010,11 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
std::istringstream llsd_data(llsd_raw);
if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
{
- LL_WARNS() << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << LL_ENDL;
+ LL_WARNS("Teleport") << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << LL_ENDL;
}
else
{
+ LL_WARNS("Teleport") << "AlertInfo llsd block received: " << llsd_block << LL_ENDL;
if(llsd_block.has("REGION_NAME"))
{
std::string region_name = llsd_block["REGION_NAME"].asString();
@@ -5988,6 +6030,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
{
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
+ LL_WARNS("Teleport") << "called handle_teleport_access_blocked, setting state to TELEPORT_NONE" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
return;
@@ -6010,22 +6053,27 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
args["REASON"] = message_id;
}
}
+ LL_WARNS("Teleport") << "Displaying CouldNotTeleportReason string, REASON= " << args["REASON"] << LL_ENDL;
LLNotificationsUtil::add("CouldNotTeleportReason", args);
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
+ LL_WARNS("Teleport") << "End of process_teleport_failed(). Reason message arg is " << args["REASON"]
+ << ". Setting state to TELEPORT_NONE" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
}
void process_teleport_local(LLMessageSystem *msg,void**)
{
+ LL_INFOS("Teleport","Messaging") << "Received TeleportLocal message" << LL_ENDL;
+
LLUUID agent_id;
msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
if (agent_id != gAgent.getID())
{
- LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+ LL_WARNS("Teleport", "Messaging") << "Got teleport notification for wrong agent " << agent_id << " expected " << gAgent.getID() << ", ignoring!" << LL_ENDL;
return;
}
@@ -6037,6 +6085,7 @@ void process_teleport_local(LLMessageSystem *msg,void**)
msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
+ LL_INFOS("Teleport") << "Message params are location_id " << location_id << " teleport_flags " << teleport_flags << LL_ENDL;
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL )
@@ -6049,6 +6098,8 @@ void process_teleport_local(LLMessageSystem *msg,void**)
}
else
{
+ LL_WARNS("Teleport") << "State is not TELEPORT_LOCAL: " << gAgent.getTeleportStateName()
+ << ", setting state to TELEPORT_NONE" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
}
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index a593905060..be05ac0d3a 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -130,7 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file)
"https://secondlife.aditi.lindenlab.com/helpers/",
DEFAULT_LOGIN_PAGE,
SL_UPDATE_QUERY_URL,
- "https://my.aditi.lindenlab.com/",
+ "https://my.secondlife-beta.com/",
"Aditi");
LLSD other_grids;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 17e61d3a0d..b88baf6aa7 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -268,6 +268,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mData(NULL),
mAudioSourcep(NULL),
mAudioGain(1.f),
+ mSoundCutOffRadius(0.f),
mAppAngle(0.f),
mPixelArea(1024.f),
mInventory(NULL),
@@ -283,6 +284,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mOnActiveList(FALSE),
mOnMap(FALSE),
mStatic(FALSE),
+ mSeatCount(0),
mNumFaces(0),
mRotTime(0.f),
mAngularVelocityRot(),
@@ -894,7 +896,12 @@ void LLViewerObject::addChild(LLViewerObject *childp)
if(childp->setParent(this))
{
mChildList.push_back(childp);
- childp->afterReparent();
+ childp->afterReparent();
+
+ if (childp->isAvatar())
+ {
+ mSeatCount++;
+ }
}
}
@@ -923,6 +930,11 @@ void LLViewerObject::removeChild(LLViewerObject *childp)
{
childp->setParent(NULL);
}
+
+ if (childp->isAvatar())
+ {
+ mSeatCount--;
+ }
break;
}
}
@@ -980,21 +992,10 @@ BOOL LLViewerObject::isChild(LLViewerObject *childp) const
return FALSE;
}
-
// returns TRUE if at least one avatar is sitting on this object
BOOL LLViewerObject::isSeat() const
{
- for (child_list_t::const_iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if (child->isAvatar())
- {
- return TRUE;
- }
- }
- return FALSE;
-
+ return mSeatCount > 0;
}
BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
@@ -1245,6 +1246,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
LLUUID audio_uuid;
LLUUID owner_id; // only valid if audio_uuid or particle system is not null
F32 gain;
+ F32 cutoff;
U8 sound_flags;
mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num);
@@ -1253,6 +1255,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// HACK: Owner id only valid if non-null sound id or particle system
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num );
mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num );
+ mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num );
mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num);
@@ -1261,6 +1264,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
mTotalCRC = crc;
+ mSoundCutOffRadius = cutoff;
// Owner ID used for sound muting or particle system muting
setAttachedSound(audio_uuid, owner_id, gain, sound_flags);
@@ -1957,6 +1961,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
mTotalCRC = crc;
+ mSoundCutOffRadius = cutoff;
setAttachedSound(sound_uuid, owner_id, gain, sound_flags);
@@ -2982,6 +2987,7 @@ void LLViewerObject::fetchInventoryFromServer()
if (!isInventoryPending())
{
delete mInventory;
+ mInventory = NULL;
// Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
@@ -4794,7 +4800,7 @@ LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id)
}
LLVOAvatar* avatar = getAvatar();
- if (avatar)
+ if (avatar && !isHUDAttachment())
{
LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id);
LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex);
@@ -5912,6 +5918,8 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) )
{
//LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL;
+ // recheck cutoff radius in case this update was an object-update with new value
+ mAudioSourcep->checkCutOffRadius();
mAudioSourcep->play(audio_uuid);
}
}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index e9ae26939a..250c4ac328 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -114,7 +114,7 @@ class LLViewerObject
public LLTrace::MemTrackable<LLViewerObject>
{
protected:
- ~LLViewerObject(); // use unref()
+ virtual ~LLViewerObject(); // use unref()
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter
@@ -403,6 +403,7 @@ public:
// Owner id is this object's owner
void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags);
void adjustAudioGain(const F32 gain);
+ F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; }
void clearAttachedSound() { mAudioSourcep = NULL; }
// Create if necessary
@@ -790,6 +791,7 @@ protected:
LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object.
LLAudioSourceVO* mAudioSourcep;
F32 mAudioGain;
+ F32 mSoundCutOffRadius;
F32 mAppAngle; // Apparent visual arc in degrees
F32 mPixelArea; // Apparent area in pixels
@@ -830,6 +832,7 @@ protected:
BOOL mOnActiveList;
BOOL mOnMap; // On the map.
BOOL mStatic; // Object doesn't move.
+ S32 mSeatCount;
S32 mNumFaces;
F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 00a652384c..6365df09e1 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -1116,10 +1116,6 @@ void LLOcclusionCullingGroup::checkOcclusion()
LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_WAIT);
while (!available && max_loop-- > 0)
{
- //do some usefu work while we wait
- F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f);
- LLAppViewer::instance()->updateTextureThreads(max_time);
-
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
}
}
@@ -1272,7 +1268,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
{
LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER);
- LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
+ LLGLSquashToFarClip squash;
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
diff --git a/indra/newview/llviewerparcelaskplay.cpp b/indra/newview/llviewerparcelaskplay.cpp
new file mode 100644
index 0000000000..afbe2c94de
--- /dev/null
+++ b/indra/newview/llviewerparcelaskplay.cpp
@@ -0,0 +1,306 @@
+/**
+ * @file llviewerparcelaskplay.cpp
+ * @brief stores data about parcel media user wants to auto-play and shows related notifications
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerparcelaskplay.h"
+
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llagent.h"
+#include "llsdserialize.h"
+
+#include <boost/lexical_cast.hpp>
+
+
+// class LLViewerParcelAskPlay
+
+LLViewerParcelAskPlay::LLViewerParcelAskPlay() :
+pNotification(NULL)
+{
+}
+
+LLViewerParcelAskPlay::~LLViewerParcelAskPlay()
+{
+
+}
+
+void LLViewerParcelAskPlay::initSingleton()
+{
+
+}
+void LLViewerParcelAskPlay::cleanupSingleton()
+{
+ if (LLNotifications::instanceExists())
+ {
+ cancelNotification();
+ }
+}
+
+void LLViewerParcelAskPlay::askToPlay(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, ask_callback cb)
+{
+ EAskPlayMode mode = getPlayMode(region_id, parcel_id);
+
+ switch (mode)
+ {
+ case ASK_PLAY_IGNORE:
+ cb(region_id, parcel_id, url, false);
+ break;
+ case ASK_PLAY_PLAY:
+ cb(region_id, parcel_id, url, true);
+ break;
+ case ASK_PLAY_ASK:
+ default:
+ {
+ // create or re-create notification
+ // Note: will create and immediately cancel one notification if region has both media and music
+ // since ask play does not distinguish media from music and media can be used as music
+ cancelNotification();
+
+ if (LLStartUp::getStartupState() > STATE_PRECACHE)
+ {
+ LLSD args;
+ args["URL"] = url;
+ LLSD payload;
+ payload["url"] = url; // or we can extract it from notification["substitutions"]
+ payload["parcel_id"] = parcel_id;
+ payload["region_id"] = region_id;
+ pNotification = LLNotificationsUtil::add("ParcelPlayingMedia", args, payload, boost::bind(onAskPlayResponse, _1, _2, cb));
+ }
+ else
+ {
+ // workaround: avoid 'new notifications arrived' on startup and just play
+ // (alternative: move to different channel, may be create new one...)
+ cb(region_id, parcel_id, url, true);
+ }
+ }
+ }
+}
+
+void LLViewerParcelAskPlay::cancelNotification()
+{
+ if (pNotification)
+ {
+ if (!pNotification->isCancelled())
+ {
+ // Force a responce
+ // Alternative is to mark notification as unique
+ pNotification->setIgnored(false);
+ LLNotifications::getInstance()->cancel(pNotification);
+ }
+ pNotification = NULL;
+ }
+}
+
+void LLViewerParcelAskPlay::resetCurrentParcelSetting()
+{
+ LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (agent_parcel && gAgent.getRegion())
+ {
+ LLViewerParcelAskPlay::resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID());
+ }
+}
+
+void LLViewerParcelAskPlay::resetSetting(const LLUUID &region_id, const S32 &parcel_id)
+{
+ region_map_t::iterator found = mRegionMap.find(region_id);
+ if (found != mRegionMap.end())
+ {
+ found->second.erase(parcel_id);
+ }
+}
+
+void LLViewerParcelAskPlay::resetSettings()
+{
+ if (LLViewerParcelAskPlay::instanceExists())
+ {
+ LLViewerParcelAskPlay::getInstance()->mRegionMap.clear();
+ }
+ LLFile::remove(getAskPlayFilename());
+}
+
+void LLViewerParcelAskPlay::setSetting(const LLUUID &region_id, const S32 &parcel_id, const LLViewerParcelAskPlay::ParcelData &data)
+{
+ mRegionMap[region_id][parcel_id] = data;
+}
+
+LLViewerParcelAskPlay::ParcelData* LLViewerParcelAskPlay::getSetting(const LLUUID &region_id, const S32 &parcel_id)
+{
+ region_map_t::iterator found = mRegionMap.find(region_id);
+ if (found != mRegionMap.end())
+ {
+ parcel_data_map_t::iterator found_parcel = found->second.find(parcel_id);
+ if (found_parcel != found->second.end())
+ {
+ return &(found_parcel->second);
+ }
+ }
+ return NULL;
+}
+
+LLViewerParcelAskPlay::EAskPlayMode LLViewerParcelAskPlay::getPlayMode(const LLUUID &region_id, const S32 &parcel_id)
+{
+ EAskPlayMode mode = ASK_PLAY_ASK;
+ ParcelData* data = getSetting(region_id, parcel_id);
+ if (data)
+ {
+ mode = data->mMode;
+ // refresh date
+ data->mDate = LLDate::now();
+ }
+ return mode;
+}
+
+void LLViewerParcelAskPlay::setPlayMode(const LLUUID &region_id, const S32 &parcel_id, LLViewerParcelAskPlay::EAskPlayMode mode)
+{
+ ParcelData data;
+ data.mMode = mode;
+ data.mDate = LLDate::now();
+ setSetting(region_id, parcel_id, data);
+}
+
+//static
+void LLViewerParcelAskPlay::onAskPlayResponse(const LLSD& notification, const LLSD& response, ask_callback cb)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ LLUUID region_id = notification["payload"]["region_id"];
+ S32 parcel_id = notification["payload"]["parcel_id"];
+ std::string url = notification["payload"]["url"];
+
+ bool play = option == 1;
+
+ cb(region_id, parcel_id, url, play);
+
+ LLViewerParcelAskPlay *inst = getInstance();
+ bool save_choice = inst->pNotification->isIgnored(); // checkbox selected
+ if (save_choice)
+ {
+ EAskPlayMode mode = (play) ? ASK_PLAY_PLAY : ASK_PLAY_IGNORE;
+ inst->setPlayMode(region_id, parcel_id, mode);
+ }
+}
+
+// static
+std::string LLViewerParcelAskPlay::getAskPlayFilename()
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_autoplay.xml");
+}
+
+void LLViewerParcelAskPlay::loadSettings()
+{
+ mRegionMap.clear();
+
+ std::string path = getAskPlayFilename();
+ if (!gDirUtilp->fileExists(path))
+ {
+ return;
+ }
+
+ LLSD autoplay_llsd;
+ llifstream file;
+ file.open(path.c_str());
+ if (!file.is_open())
+ {
+ return;
+ }
+ S32 status = LLSDSerialize::fromXML(autoplay_llsd, file);
+ file.close();
+
+ if (status == LLSDParser::PARSE_FAILURE || !autoplay_llsd.isMap())
+ {
+ return;
+ }
+
+ for (LLSD::map_const_iterator iter_region = autoplay_llsd.beginMap();
+ iter_region != autoplay_llsd.endMap(); ++iter_region)
+ {
+ LLUUID region_id = LLUUID(iter_region->first);
+ mRegionMap[region_id] = parcel_data_map_t();
+
+ const LLSD &parcel_map = iter_region->second;
+
+ if (parcel_map.isMap())
+ {
+ for (LLSD::map_const_iterator iter_parcel = parcel_map.beginMap();
+ iter_parcel != parcel_map.endMap(); ++iter_parcel)
+ {
+ if (!iter_parcel->second.isMap())
+ {
+ break;
+ }
+ S32 parcel_id = boost::lexical_cast<S32>(iter_parcel->first.c_str());
+ ParcelData data;
+ data.mMode = (EAskPlayMode)(iter_parcel->second["mode"].asInteger());
+ data.mDate = iter_parcel->second["date"].asDate();
+ mRegionMap[region_id][parcel_id] = data;
+ }
+ }
+ }
+}
+
+void LLViewerParcelAskPlay::saveSettings()
+{
+ LLSD write_llsd;
+ std::string key;
+ for (region_map_t::iterator iter_region = mRegionMap.begin();
+ iter_region != mRegionMap.end(); ++iter_region)
+ {
+ if (iter_region->second.empty())
+ {
+ continue;
+ }
+ key = iter_region->first.asString();
+ write_llsd[key] = LLSD();
+
+ for (parcel_data_map_t::iterator iter_parcel = iter_region->second.begin();
+ iter_parcel != iter_region->second.end(); ++iter_parcel)
+ {
+ if ((iter_parcel->second.mDate.secondsSinceEpoch() + (F64SecondsImplicit)U32Days(30)) > LLTimer::getTotalSeconds())
+ {
+ // write unexpired parcels
+ std::string parcel_id = boost::lexical_cast<std::string>(iter_parcel->first);
+ write_llsd[key][parcel_id] = LLSD();
+ write_llsd[key][parcel_id]["mode"] = (LLSD::Integer)iter_parcel->second.mMode;
+ write_llsd[key][parcel_id]["date"] = iter_parcel->second.mDate;
+ }
+ }
+ }
+
+ llofstream file;
+ file.open(getAskPlayFilename().c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(write_llsd, file);
+ file.close();
+ }
+}
+
diff --git a/indra/newview/llviewerparcelaskplay.h b/indra/newview/llviewerparcelaskplay.h
new file mode 100644
index 0000000000..dc711917d2
--- /dev/null
+++ b/indra/newview/llviewerparcelaskplay.h
@@ -0,0 +1,89 @@
+/**
+ * @file llviewerparcelaskplay.h
+ * @brief stores data about parcel media user wants to auto-play and shows related notifications
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * 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$
+ */
+
+#ifndef LLVIEWERPARCELASKPLAY_H
+#define LLVIEWERPARCELASKPLAY_H
+
+#include "llnotificationptr.h"
+#include "lluuid.h"
+
+class LLViewerParcelAskPlay : public LLSingleton<LLViewerParcelAskPlay>
+{
+ LLSINGLETON(LLViewerParcelAskPlay);
+ ~LLViewerParcelAskPlay();
+ void initSingleton();
+ void cleanupSingleton();
+public:
+ // functor expects functor(region_id, parcel_id, url, play/stop)
+ typedef boost::function<void(const LLUUID&, const S32&, const std::string&, const bool&)> ask_callback;
+ void askToPlay(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, ask_callback cb);
+ void cancelNotification();
+
+ void resetCurrentParcelSetting();
+ void resetSetting(const LLUUID &region_id, const S32 &parcel_id);
+ static void resetSettings();
+
+ void loadSettings();
+ void saveSettings();
+
+ S32 hasData() { return !mRegionMap.empty(); } // subsitution for 'isInitialized'
+
+private:
+ enum EAskPlayMode{
+ ASK_PLAY_IGNORE = 0,
+ ASK_PLAY_PLAY,
+ ASK_PLAY_ASK
+ };
+
+ class ParcelData
+ {
+ public:
+ LLDate mDate;
+ EAskPlayMode mMode;
+ };
+
+ void setSetting(const LLUUID &region_id, const S32 &parcel_id, const ParcelData &data);
+ ParcelData* getSetting(const LLUUID &region_id, const S32 &parcel_id);
+ EAskPlayMode getPlayMode(const LLUUID &region_id, const S32 &parcel_id);
+ void setPlayMode(const LLUUID &region_id, const S32 &parcel_id, EAskPlayMode);
+
+ static void onAskPlayResponse(const LLSD& notification, const LLSD& response, ask_callback cb);
+
+ static std::string getAskPlayFilename();
+
+private:
+ // Variables
+
+ typedef std::map<S32, ParcelData> parcel_data_map_t;
+ typedef std::map<LLUUID, parcel_data_map_t> region_map_t;
+ region_map_t mRegionMap;
+
+ // only one notification is supposed to exists and be visible
+ LLNotificationPtr pNotification;
+};
+
+
+#endif // LLVIEWERPARCELASKPLAY_H
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index b1b5275f82..83b05e6b4d 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -52,6 +52,10 @@ mMediaParcelLocalID(0)
LLMessageSystem* msg = gMessageSystem;
msg->setHandlerFunc("ParcelMediaCommandMessage", parcelMediaCommandMessageHandler );
msg->setHandlerFunc("ParcelMediaUpdate", parcelMediaUpdateHandler );
+
+ // LLViewerParcelMediaAutoPlay will regularly check and autoplay media,
+ // might be good idea to just integrate it into LLViewerParcelMedia
+ LLSingleton<LLViewerParcelMediaAutoPlay>::getInstance();
}
LLViewerParcelMedia::~LLViewerParcelMedia()
@@ -80,11 +84,13 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
S32 parcelid = parcel->getLocalID();
LLUUID regionid = gAgent.getRegion()->getRegionID();
+ bool location_changed = false;
if (parcelid != mMediaParcelLocalID || regionid != mMediaRegionID)
{
LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
mMediaParcelLocalID = parcelid;
mMediaRegionID = regionid;
+ location_changed = true;
}
std::string mediaUrl = std::string ( parcel->getMediaURL () );
@@ -102,6 +108,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
if(mMediaImpl.isNull())
{
+ // media will be autoplayed by LLViewerParcelMediaAutoPlay
return;
}
@@ -110,8 +117,9 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
|| ( mMediaImpl->getMediaTextureID() != parcel->getMediaID() )
|| ( mMediaImpl->getMimeType() != parcel->getMediaType() ))
{
- // Only play if the media types are the same.
- if(mMediaImpl->getMimeType() == parcel->getMediaType())
+ // Only play if the media types are the same and parcel stays same.
+ if(mMediaImpl->getMimeType() == parcel->getMediaType()
+ && !location_changed)
{
play(parcel);
}
@@ -127,25 +135,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
stop();
}
}
- /*
- else
- {
- // no audio player, do a first use dialog if there is media here
- if (parcel)
- {
- std::string mediaUrl = std::string ( parcel->getMediaURL () );
- if (!mediaUrl.empty ())
- {
- if (gWarningSettings.getBOOL("QuickTimeInstalled"))
- {
- gWarningSettings.setBOOL("QuickTimeInstalled", FALSE);
-
- LLNotificationsUtil::add("NoQuickTime" );
- };
- }
- }
- }
- */
}
// static
diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp
index b5a76ccba2..db8fcb4dc4 100644
--- a/indra/newview/llviewerparcelmediaautoplay.cpp
+++ b/indra/newview/llviewerparcelmediaautoplay.cpp
@@ -24,17 +24,20 @@
* $/LicenseInfo$
*/
+
#include "llviewerprecompiledheaders.h"
+
#include "llviewerparcelmediaautoplay.h"
-#include "llviewerparcelmedia.h"
+
+#include "llparcel.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
-#include "llviewerregion.h"
-#include "llparcel.h"
+#include "llviewerparcelaskplay.h"
+#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
-#include "lluuid.h"
-#include "message.h"
+#include "llviewerregion.h"
#include "llviewertexturelist.h" // for texture stats
+#include "message.h"
#include "llagent.h"
#include "llmimetypes.h"
@@ -122,11 +125,28 @@ BOOL LLViewerParcelMediaAutoPlay::tick()
{
if (this_parcel)
{
- if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable"))
+ static LLCachedControl<S32> autoplay_mode(gSavedSettings, "ParcelMediaAutoPlayEnable");
+
+ switch (autoplay_mode())
{
- // and last but not least, only play when autoplay is enabled
- LLViewerParcelMedia::getInstance()->play(this_parcel);
- }
+ case 0:
+ // Disabled
+ break;
+ case 1:
+ // Play, default value for ParcelMediaAutoPlayEnable
+ LLViewerParcelMedia::getInstance()->play(this_parcel);
+ break;
+ case 2:
+ default:
+ {
+ // Ask
+ LLViewerParcelAskPlay::getInstance()->askToPlay(this_region->getRegionID(),
+ this_parcel->getLocalID(),
+ this_parcel->getMediaURL(),
+ onStartMediaResponse);
+ break;
+ }
+ }
}
mPlayed = TRUE;
@@ -139,5 +159,18 @@ BOOL LLViewerParcelMediaAutoPlay::tick()
return FALSE; // continue ticking forever please.
}
-
+//static
+void LLViewerParcelMediaAutoPlay::onStartMediaResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play)
+{
+ if (play)
+ {
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ // make sure we are still there
+ if (parcel->getLocalID() == parcel_id && gAgent.getRegion()->getRegionID() == region_id)
+ {
+ LLViewerParcelMedia::getInstance()->play(parcel);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h
index 33565307f2..d71fd4c075 100644
--- a/indra/newview/llviewerparcelmediaautoplay.h
+++ b/indra/newview/llviewerparcelmediaautoplay.h
@@ -39,6 +39,10 @@ public:
static void playStarted();
private:
+ // for askToPlay
+ static void onStartMediaResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play);
+
+ private:
S32 mLastParcelID;
LLUUID mLastRegionID;
BOOL mPlayed;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 6cc88d0c0b..06172e366d 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -42,6 +42,7 @@
// Viewer includes
#include "llagent.h"
#include "llagentaccess.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
//#include "llfirstuse.h"
@@ -69,6 +70,8 @@
#include "llvieweraudio.h"
#include "llcorehttputil.h"
+#include "llenvironment.h"
+
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
@@ -645,6 +648,31 @@ LLParcel *LLViewerParcelMgr::getAgentParcel() const
return mAgentParcel;
}
+
+LLParcel * LLViewerParcelMgr::getAgentOrSelectedParcel() const
+{
+ LLParcel *parcel(nullptr);
+
+ LLParcelSelectionHandle sel_handle(getFloatingParcelSelection());
+ if (sel_handle)
+ {
+ LLParcelSelection *selection(sel_handle.get());
+ if (selection)
+ {
+ parcel = selection->getParcel();
+ if (parcel && (parcel->getLocalID() == INVALID_PARCEL_ID))
+ {
+ parcel = NULL;
+ }
+ }
+ }
+
+ if (!parcel)
+ parcel = LLViewerParcelMgr::instance().getAgentParcel();
+
+ return parcel;
+}
+
// Return whether the agent can build on the land they are on
bool LLViewerParcelMgr::allowAgentBuild() const
{
@@ -1285,6 +1313,13 @@ const std::string& LLViewerParcelMgr::getAgentParcelName() const
}
+const S32 LLViewerParcelMgr::getAgentParcelId() const
+{
+ if (mAgentParcel)
+ return mAgentParcel->getLocalID();
+ return INVALID_PARCEL_ID;
+}
+
void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
{
if(!parcel)
@@ -1515,6 +1550,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
BOOL region_deny_transacted_override = false; // Deprecated
BOOL region_deny_age_unverified_override = false;
BOOL region_allow_access_override = true;
+ BOOL region_allow_environment_override = true;
+ S32 parcel_environment_version = 0;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
S32 other_clean_time = 0;
@@ -1605,6 +1642,12 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
+ if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))
+ {
+ msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version);
+ msg->getBOOLFast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_RegionAllowEnvironmentOverride, region_allow_environment_override);
+ }
+
msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
LL_DEBUGS("ParcelMgr") << "Processing parcel " << local_id << " update, target(sequence): " << sequence_id << LL_ENDL;
@@ -1624,6 +1667,9 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
}
+ S32 cur_parcel_environment_version = parcel->getParcelEnvironmentVersion();
+ bool environment_changed = (cur_parcel_environment_version != parcel_environment_version);
+
parcel->init(owner_id,
FALSE, FALSE, FALSE,
claim_date, claim_price_per_meter, rent_price_per_meter,
@@ -1649,6 +1695,9 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override);
parcel->setRegionAllowAccessOverride(region_allow_access_override);
+ parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);
+ parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1666,9 +1715,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// Let interesting parties know about agent parcel change.
LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance();
- // Notify anything that wants to know when the agent changes parcels
- gAgent.changeParcels();
-
if (instance->mTeleportInProgress)
{
instance->mTeleportInProgress = FALSE;
@@ -1682,12 +1728,24 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
instance->mTeleportFinishedSignal(instance->mTeleportInProgressPosition, false);
}
}
- }
- else if (agent_parcel_update)
- {
- // updated agent parcel
- parcel_mgr.mAgentParcel->unpackMessage(msg);
- }
+ parcel->setParcelEnvironmentVersion(parcel_environment_version);
+ LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL;
+
+ // Notify anything that wants to know when the agent changes parcels
+ gAgent.changeParcels();
+ instance->mTeleportInProgress = FALSE;
+ }
+ else if (agent_parcel_update)
+ {
+ parcel->setParcelEnvironmentVersion(parcel_environment_version);
+ // updated agent parcel
+ parcel_mgr.mAgentParcel->unpackMessage(msg);
+ if ((LLEnvironment::instance().isExtendedEnvironmentEnabled() && environment_changed))
+ {
+ LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL;
+ LLEnvironment::instance().requestParcel(local_id);
+ }
+ }
}
// Handle updating selections, if necessary.
@@ -1832,6 +1890,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// Only update stream if parcel changed (recreated) or music is playing (enabled)
if (!agent_parcel_update || gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
{
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
std::string music_url_raw = parcel->getMusicURL();
// Trim off whitespace from front and back
@@ -1841,9 +1900,14 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// If there is a new music URL and it's valid, play it.
if (music_url.size() > 12)
{
- if (music_url.substr(0, 7) == "http://")
+ if (music_url.substr(0, 7) == "http://"
+ || music_url.substr(0, 8) == "https://")
{
- optionally_start_music(music_url);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender());
+ if (region)
+ {
+ optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
+ }
}
else
{
@@ -1864,25 +1928,61 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else
{
// Public land has no music
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}//if gAudiop
};
}
-void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
+//static
+void LLViewerParcelMgr::onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play)
+{
+ if (play)
+ {
+ LL_INFOS("ParcelMgr") << "Starting parcel music " << url << LL_ENDL;
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(url);
+ }
+}
+
+void LLViewerParcelMgr::optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id)
{
- if (gSavedSettings.getBOOL("AudioStreamingMusic"))
+ static LLCachedControl<bool> streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+ if (streaming_music)
{
+ static LLCachedControl<S32> autoplay_mode(gSavedSettings, "ParcelMediaAutoPlayEnable", 1);
+ static LLCachedControl<bool> tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true);
// only play music when you enter a new parcel if the UI control for this
// was not *explicitly* stopped by the user. (part of SL-4878)
LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
- if ((nearby_media_panel &&
- nearby_media_panel->getParcelAudioAutoStart()) ||
- // or they have expressed no opinion in the UI, but have autoplay on...
- (!nearby_media_panel &&
- gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
+
+ // ask mode //todo constants
+ if (autoplay_mode == 2)
+ {
+ // stop previous stream
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+
+ // if user set media to play - ask
+ if ((nearby_media_panel && nearby_media_panel->getParcelAudioAutoStart())
+ || (!nearby_media_panel && tentative_autoplay))
+ {
+ LLViewerParcelAskPlay::getInstance()->askToPlay(region_id,
+ local_id,
+ music_url,
+ onStartMusicResponse);
+ }
+ else
+ {
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
+ }
+ }
+ // autoplay
+ else if ((nearby_media_panel
+ && nearby_media_panel->getParcelAudioAutoStart())
+ // or they have expressed no opinion in the UI, but have autoplay on...
+ || (!nearby_media_panel
+ && autoplay_mode == 1
+ && tentative_autoplay))
{
LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL;
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
@@ -2577,3 +2677,9 @@ void LLViewerParcelMgr::onTeleportFailed()
{
mTeleportFailedSignal();
}
+
+bool LLViewerParcelMgr::getTeleportInProgress()
+{
+ return mTeleportInProgress // case where parcel data arrives after teleport
+ || gAgent.getTeleportState() > LLAgent::TELEPORT_NONE; // For LOCAL, no mTeleportInProgress
+}
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 29219843c9..508a63c398 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -154,6 +154,7 @@ public:
//LLParcel *getParcelSelection() const;
LLParcel *getAgentParcel() const;
+ LLParcel *getAgentOrSelectedParcel() const;
BOOL inAgentParcel(const LLVector3d &pos_global) const;
@@ -262,13 +263,15 @@ public:
// accessors for mAgentParcel
const std::string& getAgentParcelName() const;
+ const S32 getAgentParcelId() const;
// Create a landmark at the "appropriate" location for the
// currently selected parcel.
// *NOTE: Taken out 2005-03-21. Phoenix.
//void makeLandmarkAtSelection();
- static void optionally_start_music(const std::string& music_url);
+ static void onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play);
+ static void optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id);
static void processParcelOverlay(LLMessageSystem *msg, void **user_data);
static void processParcelProperties(LLMessageSystem *msg, void **user_data);
@@ -285,6 +288,7 @@ public:
boost::signals2::connection setTeleportFailedCallback(teleport_failed_callback_t cb);
void onTeleportFinished(bool local, const LLVector3d& new_pos);
void onTeleportFailed();
+ bool getTeleportInProgress();
static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power);
static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power);
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 998ae52fe0..f042040e98 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -136,7 +136,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
{
mOwnerAvatarp = find_avatar(mOwnerUUID);
}
- if (mOwnerAvatarp.notNull() && LLVOAvatar::AV_DO_NOT_RENDER == mOwnerAvatarp->getVisualMuteSettings())
+ if (mOwnerAvatarp.notNull() && LLVOAvatar::AOA_NORMAL != mOwnerAvatarp->getOverallAppearance())
{
return;
}
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 999d9092bd..bbbacce8fa 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -29,6 +29,8 @@
#ifndef LL_LLVIEWERPRECOMPILEDHEADERS_H
#define LL_LLVIEWERPRECOMPILEDHEADERS_H
+#include "llwin32headers.h"
+
// This file MUST be the first one included by each .cpp file
// in viewer.
// It is used to precompile headers for improved build speed.
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 75e707aaa3..2fde4fe49c 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -80,6 +80,7 @@
#include "lleventcoro.h"
#include "llcorehttputil.h"
#include "llcallstack.h"
+#include "llsettingsdaycycle.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -101,6 +102,7 @@ const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
S32 LLViewerRegion::sLastCameraUpdated = 0;
S32 LLViewerRegion::sNewObjectCreationThrottle = -1;
+LLViewerRegion::vocache_entry_map_t LLViewerRegion::sRegionCacheCleanup;
typedef std::map<std::string, std::string> CapabilityMap;
@@ -289,13 +291,21 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
<< " region name " << regionp->getName()
+ << " region id " << regionp->getRegionID()
+ << " handle " << regionp->getHandle()
<< " (attempt #" << mSeedCapAttempts + 1 << ")" << LL_ENDL;
+ LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;
regionp = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
++mSeedCapAttempts;
+ if (LLApp::isExiting())
+ {
+ return;
+ }
+
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
@@ -342,9 +352,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
log_capabilities(mCapabilities);
#endif
+ LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle
+ << " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
- LL_DEBUGS("AppInit", "Capabilities") << "received caps for handle " << regionHandle
- << " region name " << regionp->getName() << LL_ENDL;
if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
{
@@ -397,7 +407,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
LLSD capabilityNames = LLSD::emptyArray();
buildCapabilityNames(capabilityNames);
- LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << " for region " << regionp->getRegionID() << LL_ENDL;
regionp = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
@@ -410,6 +420,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
break; // no retry
}
+ if (LLApp::isExiting())
+ {
+ break;
+ }
+
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
@@ -513,6 +528,11 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
continue;
}
+ if (LLApp::isExiting())
+ {
+ break;
+ }
+
// remove the http_result from the llsd
result.erase("http_result");
@@ -607,6 +627,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
+ mImpl->mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR
+ mImpl->mObjectPartition.push_back(new LLControlAVPartition(this)); //PARTITION_CONTROL_AV
mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
@@ -631,6 +653,9 @@ void LLViewerRegion::initStats()
mAlive = false; // can become false if circuit disconnects
}
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects");
+static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache");
+
LLViewerRegion::~LLViewerRegion()
{
mDead = TRUE;
@@ -645,7 +670,10 @@ LLViewerRegion::~LLViewerRegion()
disconnectAllNeighbors();
LLViewerPartSim::getInstance()->cleanupRegion(this);
- gObjectList.killObjects(this);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS);
+ gObjectList.killObjects(this);
+ }
delete mImpl->mCompositionp;
delete mParcelOverlay;
@@ -656,7 +684,10 @@ LLViewerRegion::~LLViewerRegion()
#endif
std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
- saveObjectCache();
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE);
+ saveObjectCache();
+ }
delete mImpl;
mImpl = NULL;
@@ -725,6 +756,8 @@ void LLViewerRegion::saveObjectCache()
mCacheDirty = FALSE;
}
+ // Map of LLVOCacheEntry takes time to release, store map for cleanup on idle
+ sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end());
mImpl->mCacheMap.clear();
}
@@ -1486,6 +1519,16 @@ void LLViewerRegion::idleUpdate(F32 max_update_time)
return;
}
+// static
+void LLViewerRegion::idleCleanup(F32 max_update_time)
+{
+ LLTimer update_timer;
+ while (!sRegionCacheCleanup.empty() && (max_update_time - update_timer.getElapsedTimeF32() > 0))
+ {
+ sRegionCacheCleanup.erase(sRegionCacheCleanup.begin());
+ }
+}
+
//update the throttling number for new object creation
void LLViewerRegion::calcNewObjectCreationThrottle()
{
@@ -2180,7 +2223,7 @@ void LLViewerRegion::requestSimulatorFeatures()
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
- LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
else
{
@@ -2895,6 +2938,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EstateAccess");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
+ capabilityNames.append("ExtEnvironment");
capabilityNames.append("FetchLib2");
capabilityNames.append("FetchLibDescendents2");
@@ -2916,6 +2960,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("IsExperienceAdmin");
capabilityNames.append("IsExperienceContributor");
capabilityNames.append("RegionExperiences");
+ capabilityNames.append("ExperienceQuery");
capabilityNames.append("GetMetadata");
capabilityNames.append("GetObjectCost");
capabilityNames.append("GetObjectPhysicsData");
@@ -2966,9 +3011,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateNotecardTaskInventory");
capabilityNames.append("UpdateScriptAgent");
capabilityNames.append("UpdateScriptTask");
+ capabilityNames.append("UpdateSettingsAgentInventory");
+ capabilityNames.append("UpdateSettingsTaskInventory");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
+ capabilityNames.append("ViewerBenefits");
capabilityNames.append("ViewerMetrics");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
@@ -2982,7 +3030,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
if (getCapability("Seed") == url)
{
setCapabilityDebug("Seed", url);
- LL_WARNS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
+ LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " <<
url << LL_ENDL;
//Instead of just returning we build up a second set of seed caps and compare them
@@ -3003,7 +3051,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, mImpl, getHandle()));
- LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
S32 LLViewerRegion::getNumSeedCapRetries()
@@ -3137,7 +3185,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
{
mCapabilitiesReceivedSignal(getRegionID());
- //LLFloaterPermsDefault::sendInitialPerms();
+ LLFloaterPermsDefault::sendInitialPerms();
// This is a single-shot signal. Forget callbacks to save resources.
mCapabilitiesReceivedSignal.disconnect_all_slots();
@@ -3313,5 +3361,12 @@ U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
return max_entries;
}
-
+std::string LLViewerRegion::getSimHostName()
+{
+ if (mSimulatorFeaturesReceived)
+ {
+ return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName();
+ }
+ return std::string("...");
+}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 2548ff1423..dfd8c64f76 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -86,6 +86,8 @@ public:
PARTITION_GRASS,
PARTITION_VOLUME,
PARTITION_BRIDGE,
+ PARTITION_AVATAR,
+ PARTITION_CONTROL_AV, // Animesh
PARTITION_HUD_PARTICLE,
PARTITION_VO_CACHE,
PARTITION_NONE,
@@ -131,6 +133,7 @@ public:
inline BOOL isPrelude() const;
inline BOOL getAllowTerraform() const;
inline BOOL getRestrictPushObject() const;
+ inline BOOL getAllowEnvironmentOverride() const;
inline BOOL getReleaseNotesRequested() const;
bool isAlive(); // can become false if circuit disconnects
@@ -229,6 +232,9 @@ public:
F32 getWidth() const { return mWidth; }
+ // regions are expensive to release, this function gradually releases cache from memory
+ static void idleCleanup(F32 max_update_time);
+
void idleUpdate(F32 max_update_time);
void lightIdleUpdate();
bool addVisibleGroup(LLViewerOctreeGroup* group);
@@ -387,6 +393,8 @@ public:
BOOL isPaused() const {return mPaused;}
S32 getLastUpdate() const {return mLastUpdate;}
+ std::string getSimHostName();
+
static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
private:
@@ -547,6 +555,9 @@ private:
LLSD mSimulatorFeatures;
+ typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
+ static vocache_entry_map_t sRegionCacheCleanup;
+
// the materials capability throttle
LLFrameTimer mMaterialsCapThrottleTimer;
LLFrameTimer mRenderInfoRequestTimer;
@@ -637,6 +648,11 @@ inline BOOL LLViewerRegion::getRestrictPushObject() const
return ((mRegionFlags & REGION_FLAGS_RESTRICT_PUSHOBJECT) != 0);
}
+inline BOOL LLViewerRegion::getAllowEnvironmentOverride() const
+{
+ return ((mRegionFlags & REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE) != 0);
+}
+
inline BOOL LLViewerRegion::getReleaseNotesRequested() const
{
return mReleaseNotesRequested;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 6d8b27ff2d..be5c22e7c3 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -31,27 +31,24 @@
#include "llfeaturemanager.h"
#include "llviewershadermgr.h"
-
-#include "llfile.h"
-#include "llviewerwindow.h"
-#include "llwindow.h"
#include "llviewercontrol.h"
-#include "pipeline.h"
+
+#include "llrender.h"
+#include "llenvironment.h"
+#include "llatmosphere.h"
#include "llworld.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llsky.h"
#include "llvosky.h"
-#include "llrender.h"
+
+#include "pipeline.h"
+
+#include "llfile.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
+
#include "lljoint.h"
#include "llskinningutil.h"
-#ifdef LL_RELEASE_FOR_DOWNLOAD
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
-#endif
-
static LLStaticHashedString sTexture0("texture0");
static LLStaticHashedString sTexture1("texture1");
static LLStaticHashedString sTex0("tex0");
@@ -154,6 +151,7 @@ LLGLSLShader gSkinnedObjectShinySimpleWaterProgram;
LLGLSLShader gTerrainProgram;
LLGLSLShader gTerrainWaterProgram;
LLGLSLShader gWaterProgram;
+LLGLSLShader gWaterEdgeProgram;
LLGLSLShader gUnderWaterProgram;
//interface shaders
@@ -178,7 +176,8 @@ LLGLSLShader gImpostorProgram;
// WindLight shader handles
LLGLSLShader gWLSkyProgram;
LLGLSLShader gWLCloudProgram;
-
+LLGLSLShader gWLSunProgram;
+LLGLSLShader gWLMoonProgram;
// Effects Shaders
LLGLSLShader gGlowProgram;
@@ -200,6 +199,7 @@ LLGLSLShader gDeferredSkinnedBumpProgram;
LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredBumpProgram;
LLGLSLShader gDeferredTerrainProgram;
+LLGLSLShader gDeferredTerrainWaterProgram;
LLGLSLShader gDeferredTreeProgram;
LLGLSLShader gDeferredTreeShadowProgram;
LLGLSLShader gDeferredAvatarProgram;
@@ -215,6 +215,7 @@ LLGLSLShader gDeferredSoftenWaterProgram;
LLGLSLShader gDeferredShadowProgram;
LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
+LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAvatarAlphaShadowProgram;
LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
@@ -238,6 +239,8 @@ LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
LLGLSLShader gDeferredWLCloudProgram;
+LLGLSLShader gDeferredWLSunProgram;
+LLGLSLShader gDeferredWLMoonProgram;
LLGLSLShader gDeferredStarProgram;
LLGLSLShader gDeferredFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
@@ -249,17 +252,20 @@ LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
LLViewerShaderMgr::LLViewerShaderMgr() :
- mVertexShaderLevel(SHADER_COUNT, 0),
+ mShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
-{
- /// Make sure WL Sky is the first program
- //ONLY shaders that need WL Param management should be added here
+{
+ /// Make sure WL Sky is the first program
+ //ONLY shaders that need WL Param management should be added here
mShaderList.push_back(&gWLSkyProgram);
mShaderList.push_back(&gWLCloudProgram);
+ mShaderList.push_back(&gWLSunProgram);
+ mShaderList.push_back(&gWLMoonProgram);
mShaderList.push_back(&gAvatarProgram);
mShaderList.push_back(&gObjectShinyProgram);
mShaderList.push_back(&gObjectShinyNonIndexedProgram);
mShaderList.push_back(&gWaterProgram);
+ mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gObjectSimpleProgram);
mShaderList.push_back(&gObjectSimpleImpostorProgram);
@@ -314,22 +320,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
mShaderList.push_back(&gDeferredSoftenWaterProgram);
- mShaderList.push_back(&gDeferredMaterialProgram[1]);
- mShaderList.push_back(&gDeferredMaterialProgram[5]);
- mShaderList.push_back(&gDeferredMaterialProgram[9]);
- mShaderList.push_back(&gDeferredMaterialProgram[13]);
- mShaderList.push_back(&gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[1]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[5]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[9]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[13]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]);
- mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gDeferredAlphaImpostorProgram);
mShaderList.push_back(&gDeferredAlphaWaterProgram);
@@ -345,14 +335,17 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
mShaderList.push_back(&gDeferredUnderWaterProgram);
+ mShaderList.push_back(&gDeferredTerrainWaterProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
+ mShaderList.push_back(&gDeferredWLMoonProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
}
LLViewerShaderMgr::~LLViewerShaderMgr()
{
- mVertexShaderLevel.clear();
+ mShaderLevel.clear();
mShaderList.clear();
}
@@ -389,9 +382,9 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
//============================================================================
// Set Levels
-S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)
+S32 LLViewerShaderMgr::getShaderLevel(S32 type)
{
- return LLPipeline::sDisableShaders ? 0 : mVertexShaderLevel[type];
+ return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type];
}
//============================================================================
@@ -399,306 +392,350 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)
void LLViewerShaderMgr::setShaders()
{
- //setShaders might be called redundantly by gSavedSettings, so return on reentrance
- static bool reentrance = false;
-
- if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
- {
- return;
- }
-
- 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;
- }
-
- reentrance = true;
-
- if (LLRender::sGLCoreProfile)
- {
- if (!gSavedSettings.getBOOL("VertexShaderEnable"))
- { //vertex shaders MUST be enabled to use core profile
- gSavedSettings.setBOOL("VertexShaderEnable", TRUE);
- }
- }
-
- //setup preprocessor definitions
- LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);
-
- // Make sure the compiled shader map is cleared before we recompile shaders.
- mShaderObjects.clear();
-
- initAttribsAndUniforms();
- gPipeline.releaseGLBuffers();
-
- if (gSavedSettings.getBOOL("VertexShaderEnable"))
- {
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
- LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
- LLPipeline::updateRenderDeferred();
- }
- else
- {
- LLPipeline::sRenderGlow = FALSE;
- LLPipeline::sWaterReflections = FALSE;
- }
-
- //hack to reset buffers that change behavior with shaders
- gPipeline.resetVertexBuffers();
-
- if (gViewerWindow)
- {
- gViewerWindow->setCursor(UI_CURSOR_WAIT);
- }
-
- // Lighting
- gPipeline.setLightingDetail(-1);
-
- // Shaders
- LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
- LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
-
- for (S32 i = 0; i < SHADER_COUNT; i++)
- {
- mVertexShaderLevel[i] = 0;
- }
- mMaxAvatarShaderLevel = 0;
-
- LLGLSLShader::sNoFixedFunction = false;
- LLVertexBuffer::unbind();
- if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")
- && (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10)
- && gSavedSettings.getBOOL("VertexShaderEnable"))
- {
- //using shaders, disable fixed function
- LLGLSLShader::sNoFixedFunction = true;
-
- S32 light_class = 2;
- S32 env_class = 2;
- S32 obj_class = 2;
- S32 effect_class = 2;
- S32 wl_class = 2;
- S32 water_class = 2;
- 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 (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- gSavedSettings.getBOOL("RenderDeferred") &&
- gSavedSettings.getBOOL("RenderAvatarVP") &&
- gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
- {
- if (gSavedSettings.getS32("RenderShadowDetail") > 0)
- { //shadows
- deferred_class = 2;
- }
- else
- { //no shadows
- deferred_class = 1;
- }
-
- //make sure hardware skinning is enabled
- //gSavedSettings.setBOOL("RenderAvatarVP", TRUE);
-
- //make sure atmospheric shaders are enabled
- //gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE);
- }
-
-
- if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
- && gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
- {
- // user has disabled WindLight in their settings, downgrade
- // windlight shaders to stub versions.
- wl_class = 1;
- }
-
-
- // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
- if (mVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())
- {
- gSky.mVOSkyp->forceSkyUpdate();
- }
-
-
- // Load lighting shaders
- mVertexShaderLevel[SHADER_LIGHTING] = light_class;
- mVertexShaderLevel[SHADER_INTERFACE] = light_class;
- mVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
- mVertexShaderLevel[SHADER_WATER] = water_class;
- mVertexShaderLevel[SHADER_OBJECT] = obj_class;
- mVertexShaderLevel[SHADER_EFFECT] = effect_class;
- mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
- mVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
- mVertexShaderLevel[SHADER_TRANSFORM] = transform_class;
-
- BOOL loaded = loadBasicShaders();
-
- if (loaded)
- {
- gPipeline.mVertexShadersEnabled = TRUE;
- gPipeline.mVertexShadersLoaded = 1;
-
- // Load all shaders to set max levels
- loaded = loadShadersEnvironment();
-
- if (loaded)
- {
- loaded = loadShadersWater();
- }
-
- if (loaded)
- {
- loaded = loadShadersWindLight();
- }
-
- if (loaded)
- {
- loaded = loadShadersEffects();
- }
-
- if (loaded)
- {
- loaded = loadShadersInterface();
- }
-
- if (loaded)
-
- {
- loaded = loadTransformShaders();
- }
-
- if (loaded)
- {
- // Load max avatar shaders to set the max level
- mVertexShaderLevel[SHADER_AVATAR] = 3;
- mMaxAvatarShaderLevel = 3;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
- S32 avatar_class = 1;
-
- // cloth is a class3 shader
- if(avatar_cloth)
- {
- avatar_class = 3;
- }
-
- // Set the actual level
- mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
- loadShadersAvatar();
- if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if (mVertexShaderLevel[SHADER_AVATAR] == 0)
- {
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
- }
- if(llmax(mVertexShaderLevel[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
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- mVertexShaderLevel[SHADER_DEFERRED] = 0;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP"))
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
- }
-
- loadShadersAvatar(); // unloads
-
- loaded = loadShadersObject();
- }
- }
+ //setShaders might be called redundantly by gSavedSettings, so return on reentrance
+ static bool reentrance = false;
+
+ if (!gPipeline.mInitialized || !sInitialized || reentrance || sSkipReload)
+ {
+ return;
+ }
+
+ if (!gGLManager.mHasShaderObjects
+ || !gGLManager.mHasVertexShader
+ || !gGLManager.mHasFragmentShader)
+ {
+ // Viewer will show 'hardware requirements' warning later
+ LL_INFOS("ShaderLoading") << "Shaders not supported" << LL_ENDL;
+ return;
+ }
+
+ 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;
+ }
+
+ reentrance = true;
+
+ //setup preprocessor definitions
+ LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);
+
+ // Make sure the compiled shader map is cleared before we recompile shaders.
+ mVertexShaderObjects.clear();
+ mFragmentShaderObjects.clear();
+
+ initAttribsAndUniforms();
+ gPipeline.releaseGLBuffers();
- 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);
- reentrance = false;
- setShaders();
- return;
- }
-
- if (gSavedSettings.getBOOL("VertexShaderEnable"))
- { //disable shaders outright and try again
- gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
- reentrance = false;
- setShaders();
- return;
- }
- }
-
- if (loaded && !loadShadersDeferred())
- { //everything else succeeded but deferred failed, disable deferred and try again
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- reentrance = false;
- setShaders();
- return;
- }
- }
- else
- {
- LLGLSLShader::sNoFixedFunction = false;
- gPipeline.mVertexShadersEnabled = FALSE;
- gPipeline.mVertexShadersLoaded = 0;
- mVertexShaderLevel[SHADER_LIGHTING] = 0;
- mVertexShaderLevel[SHADER_INTERFACE] = 0;
- mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
- mVertexShaderLevel[SHADER_WATER] = 0;
- mVertexShaderLevel[SHADER_OBJECT] = 0;
- mVertexShaderLevel[SHADER_EFFECT] = 0;
- mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- }
- }
- else
- {
- LLGLSLShader::sNoFixedFunction = false;
- gPipeline.mVertexShadersEnabled = FALSE;
- gPipeline.mVertexShadersLoaded = 0;
- mVertexShaderLevel[SHADER_LIGHTING] = 0;
- mVertexShaderLevel[SHADER_INTERFACE] = 0;
- mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
- mVertexShaderLevel[SHADER_WATER] = 0;
- mVertexShaderLevel[SHADER_OBJECT] = 0;
- mVertexShaderLevel[SHADER_EFFECT] = 0;
- mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- }
-
- if (gViewerWindow)
- {
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- }
- gPipeline.createGLBuffers();
+ LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
+ LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
+ LLPipeline::updateRenderDeferred();
+
+ //hack to reset buffers that change behavior with shaders
+ gPipeline.resetVertexBuffers();
+
+ if (gViewerWindow)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_WAIT);
+ }
+
+ // Lighting
+ gPipeline.setLightingDetail(-1);
+
+ // Shaders
+ LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
+ LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
+
+ for (S32 i = 0; i < SHADER_COUNT; i++)
+ {
+ mShaderLevel[i] = 0;
+ }
+ mMaxAvatarShaderLevel = 0;
+
+ LLGLSLShader::sNoFixedFunction = false;
+ LLVertexBuffer::unbind();
+
+ llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
+
+ bool canRenderDeferred = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
+ bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+ bool useRenderDeferred = canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP");
+ bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+
+ //using shaders, disable fixed function
+ LLGLSLShader::sNoFixedFunction = true;
+
+ S32 light_class = 3;
+ S32 interface_class = 2;
+ S32 env_class = 2;
+ S32 obj_class = 2;
+ S32 effect_class = 2;
+ S32 wl_class = 1;
+ S32 water_class = 2;
+ 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)
+ {
+ //shadows
+ switch (shadow_detail)
+ {
+ case 1:
+ deferred_class = 2; // PCF shadows
+ break;
+
+ case 2:
+ deferred_class = 2; // PCF shadows
+ break;
+
+ case 0:
+ default:
+ deferred_class = 1; // no shadows
+ break;
+ }
+ }
+
+ if (doingWindLight)
+ {
+ // user has disabled WindLight in their settings, downgrade
+ // windlight shaders to stub versions.
+ wl_class = 2;
+ }
+ else
+ {
+ light_class = 2;
+ }
+
+ // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
+ if (!wl_class || (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()))
+ {
+ gSky.mVOSkyp->forceSkyUpdate();
+ }
+
+ // Load lighting shaders
+ mShaderLevel[SHADER_LIGHTING] = light_class;
+ mShaderLevel[SHADER_INTERFACE] = interface_class;
+ mShaderLevel[SHADER_ENVIRONMENT] = env_class;
+ mShaderLevel[SHADER_WATER] = water_class;
+ mShaderLevel[SHADER_OBJECT] = obj_class;
+ 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)
+ {
+ LL_INFOS() << "Loaded basic shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load basic shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+
+ if (loaded)
+ {
+ gPipeline.mVertexShadersEnabled = TRUE;
+ gPipeline.mVertexShadersLoaded = 1;
+
+ // Load all shaders to set max levels
+ loaded = loadShadersEnvironment();
+
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded environment shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load environment shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersWater();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded water shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersWindLight();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded windlight shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ if (loaded)
+ {
+ LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ 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 (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
+ BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+
+ // cloth is a class3 shader
+ S32 avatar_class = avatar_cloth ? 3 : 1;
+
+ // Set the actual level
+ mShaderLevel[SHADER_AVATAR] = avatar_class;
+
+ loaded = loadShadersAvatar();
+ llassert(loaded);
+
+ if (mShaderLevel[SHADER_AVATAR] != avatar_class)
+ {
+ if (mShaderLevel[SHADER_AVATAR] == 0)
+ {
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ }
+ 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;
+
+ if (gSavedSettings.getBOOL("RenderAvatarVP"))
+ {
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ }
+
+ loadShadersAvatar(); // unloads
+
+ loaded = loadShadersObject();
+ llassert(loaded);
+ }
+ }
+
+ 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;
+ }
+ }
+ else
+ {
+ LLGLSLShader::sNoFixedFunction = false;
+ gPipeline.mVertexShadersEnabled = FALSE;
+ gPipeline.mVertexShadersLoaded = 0;
+ mShaderLevel[SHADER_LIGHTING] = 0;
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ mShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mShaderLevel[SHADER_WATER] = 0;
+ mShaderLevel[SHADER_OBJECT] = 0;
+ mShaderLevel[SHADER_EFFECT] = 0;
+ mShaderLevel[SHADER_WINDLIGHT] = 0;
+ mShaderLevel[SHADER_AVATAR] = 0;
+ }
+
+ if (gViewerWindow)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_ARROW);
+ }
+ gPipeline.createGLBuffers();
- reentrance = false;
+ reentrance = false;
}
void LLViewerShaderMgr::unloadShaders()
@@ -780,6 +817,7 @@ void LLViewerShaderMgr::unloadShaders()
gWaterProgram.unload();
+ gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
gTerrainProgram.unload();
gTerrainWaterProgram.unload();
@@ -795,6 +833,8 @@ void LLViewerShaderMgr::unloadShaders()
gWLSkyProgram.unload();
gWLCloudProgram.unload();
+ gWLSunProgram.unload();
+ gWLMoonProgram.unload();
gPostColorFilterProgram.unload();
gPostNightVisionProgram.unload();
@@ -814,15 +854,15 @@ void LLViewerShaderMgr::unloadShaders()
gTransformColorProgram.unload();
gTransformTangentProgram.unload();
- mVertexShaderLevel[SHADER_LIGHTING] = 0;
- mVertexShaderLevel[SHADER_OBJECT] = 0;
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
- mVertexShaderLevel[SHADER_WATER] = 0;
- mVertexShaderLevel[SHADER_INTERFACE] = 0;
- mVertexShaderLevel[SHADER_EFFECT] = 0;
- mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
- mVertexShaderLevel[SHADER_TRANSFORM] = 0;
+ mShaderLevel[SHADER_LIGHTING] = 0;
+ mShaderLevel[SHADER_OBJECT] = 0;
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mShaderLevel[SHADER_WATER] = 0;
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ mShaderLevel[SHADER_EFFECT] = 0;
+ mShaderLevel[SHADER_WINDLIGHT] = 0;
+ mShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mVertexShadersLoaded = 0;
}
@@ -856,7 +896,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
if (gGLManager.mIsMobileGF)
sum_lights_class = 3;
#endif
-
+
// Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
@@ -865,34 +905,55 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// (in order of shader function call depth for reference purposes, deepest level first)
vector< pair<string, S32> > shaders;
- shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
- shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
- shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
+ shaders.push_back( make_pair( "lighting/lightV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
+ 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( "avatar/avatarSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
{
- shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
+ shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
- shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
+ shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
boost::unordered_map<std::string, std::string> attribs;
attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount());
+ BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
+ BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
+ BOOL local_light_kill = gSavedSettings.getBOOL("LocalLightDisable");
+
+ if (ambient_kill)
+ {
+ attribs["AMBIENT_KILL"] = "1";
+ }
+
+ if (sunlight_kill)
+ {
+ attribs["SUNLIGHT_KILL"] = "1";
+ }
+
+ if (local_light_kill)
+ {
+ attribs["LOCAL_LIGHT_KILL"] = "1";
+ }
+
// 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)
{
+ LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
return FALSE;
}
}
@@ -908,43 +969,51 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
- std::vector<S32> index_channels;
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT]) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mVertexShaderLevel[SHADER_WATER] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
-
+ 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] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsHelpersF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
+ 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( "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] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+ index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
+
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)
{
+ LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
return FALSE;
}
}
@@ -956,7 +1025,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
+ if (mShaderLevel[SHADER_ENVIRONMENT] == 0)
{
gTerrainProgram.unload();
return TRUE;
@@ -968,19 +1037,23 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
gTerrainProgram.mFeatures.calculatesLighting = true;
gTerrainProgram.mFeatures.calculatesAtmospherics = true;
gTerrainProgram.mFeatures.hasAtmospherics = true;
+ gTerrainProgram.mFeatures.hasTransport = true;
+ gTerrainProgram.mFeatures.hasGamma = true;
+ gTerrainProgram.mFeatures.hasSrgb = true;
gTerrainProgram.mFeatures.mIndexedTextureChannels = 0;
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.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];
- success = gTerrainProgram.createShader(NULL, NULL);
+ 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.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
+ success = gTerrainProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (!success)
{
- mVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
+ mShaderLevel[SHADER_ENVIRONMENT] = 0;
return FALSE;
}
@@ -994,9 +1067,10 @@ BOOL LLViewerShaderMgr::loadShadersWater()
BOOL success = TRUE;
BOOL terrainWaterSuccess = TRUE;
- if (mVertexShaderLevel[SHADER_WATER] == 0)
+ if (mShaderLevel[SHADER_WATER] == 0)
{
gWaterProgram.unload();
+ gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
gTerrainWaterProgram.unload();
return TRUE;
@@ -1009,11 +1083,32 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.mFeatures.calculatesAtmospherics = true;
gWaterProgram.mFeatures.hasGamma = true;
gWaterProgram.mFeatures.hasTransport = true;
+ gWaterProgram.mFeatures.hasSrgb = 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.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
+ gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ // load water shader
+ gWaterEdgeProgram.mName = "Water Edge Shader";
+ gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasGamma = true;
+ gWaterEdgeProgram.mFeatures.hasTransport = true;
+ gWaterEdgeProgram.mFeatures.hasSrgb = 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.addPermutation("WATER_EDGE", "1");
+ gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ success = gWaterEdgeProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1021,13 +1116,14 @@ BOOL LLViewerShaderMgr::loadShadersWater()
//load under water vertex shader
gUnderWaterProgram.mName = "Underwater Shader";
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.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
- gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-
+ gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
+ gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gUnderWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1041,31 +1137,40 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gTerrainWaterProgram.mFeatures.disableTextureIndex = true;
gTerrainWaterProgram.mShaderFiles.clear();
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];
+ gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+
+ gTerrainWaterProgram.clearPermutations();
+
+ if (LLPipeline::RenderDeferred)
+ {
+ gTerrainWaterProgram.addPermutation("ALM", "1");
+ }
+
terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);
+ llassert(terrainWaterSuccess);
}
/// Keep track of water shader levels
- if (gWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER]
- || gUnderWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER])
+ if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
+ || gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
{
- mVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
+ mShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
}
if (!success)
{
- mVertexShaderLevel[SHADER_WATER] = 0;
+ mShaderLevel[SHADER_WATER] = 0;
return FALSE;
}
// if we failed to load the terrain water shaders and we need them (using class2 water),
// then drop down to class1 water.
- if (mVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
+ if (mShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
{
- mVertexShaderLevel[SHADER_WATER]--;
+ mShaderLevel[SHADER_WATER]--;
return loadShadersWater();
}
@@ -1078,7 +1183,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_EFFECT] == 0)
+ if (mShaderLevel[SHADER_EFFECT] == 0)
{
gGlowProgram.unload();
gGlowExtractProgram.unload();
@@ -1093,7 +1198,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
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.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
+ gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowProgram.createShader(NULL, NULL);
if (!success)
{
@@ -1107,7 +1212,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
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.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
+ gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
{
@@ -1121,7 +1226,13 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
BOOL LLViewerShaderMgr::loadShadersDeferred()
{
- if (mVertexShaderLevel[SHADER_DEFERRED] == 0)
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1;
+
+ BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
+ BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
+ BOOL local_light_kill = gSavedSettings.getBOOL("LocalLightDisable");
+
+ if (mShaderLevel[SHADER_DEFERRED] == 0)
{
gDeferredTreeProgram.unload();
gDeferredTreeShadowProgram.unload();
@@ -1136,6 +1247,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.unload();
gDeferredImpostorProgram.unload();
gDeferredTerrainProgram.unload();
+ gDeferredTerrainWaterProgram.unload();
gDeferredLightProgram.unload();
for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
{
@@ -1149,9 +1261,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenWaterProgram.unload();
gDeferredShadowProgram.unload();
gDeferredShadowCubeProgram.unload();
- gDeferredShadowAlphaMaskProgram.unload();
+ gDeferredShadowAlphaMaskProgram.unload();
+ gDeferredShadowFullbrightAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
+ gDeferredAvatarAlphaShadowProgram.unload();
+ gDeferredAvatarAlphaMaskShadowProgram.unload();
gDeferredAttachmentShadowProgram.unload();
+ gDeferredAttachmentAlphaShadowProgram.unload();
+ gDeferredAttachmentAlphaMaskShadowProgram.unload();
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
@@ -1171,6 +1288,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
+ gDeferredWLSunProgram.unload();
+ gDeferredWLMoonProgram.unload();
gDeferredStarProgram.unload();
gDeferredFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightShinyProgram.unload();
@@ -1197,7 +1316,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightProgram.createShader(NULL, NULL);
}
@@ -1207,7 +1326,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDeferredHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -1217,83 +1336,97 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDeferredHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightSpecularProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
+ 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.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDiffuseProgram.createShader(NULL, NULL);
}
if (success)
{
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.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
}
-
+
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader";
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL);
+ llassert(success);
}
-
if (success)
{
gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";
gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true;
+ gDeferredSkinnedDiffuseProgram.mFeatures.hasSrgb = true;
gDeferredSkinnedDiffuseProgram.mShaderFiles.clear();
gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader";
gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true;
gDeferredSkinnedBumpProgram.mShaderFiles.clear();
gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1304,16 +1437,47 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true;
+
gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ gDeferredSkinnedAlphaProgram.clearPermutations();
gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
- gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
- gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
+
+ if (use_sun_shadow)
+ {
+ gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ gDeferredSkinnedAlphaProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredSkinnedAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredSkinnedAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
-
+ llassert(success);
+
// Hack to include uniforms for lighting without linking in lighting file
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true;
@@ -1322,11 +1486,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredBumpProgram.createShader(NULL, NULL);
+ llassert(success);
}
gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
@@ -1351,6 +1517,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
if (success)
{
+ mShaderList.push_back(&gDeferredMaterialProgram[i]);
+
gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
U32 alpha_mode = i & 0x3;
@@ -1358,48 +1526,138 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
- gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
- gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
- gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- bool has_skin = i & 0x10;
- gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
-
- if (has_skin)
- {
- gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
- }
+ gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
- }
+ gDeferredMaterialProgram[i].clearPermutations();
- if (success)
- {
- gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
+ bool has_normal_map = (i & 0x8) > 0;
+ bool has_specular_map = (i & 0x4) > 0;
- U32 alpha_mode = i & 0x3;
+ if (has_normal_map)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+ }
- 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].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
-
- gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
- gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
- gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
- gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- bool has_skin = i & 0x10;
- gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
- gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
-
- if (has_skin)
+ if (has_specular_map)
{
- gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
}
- success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
+ if (ambient_kill)
+ {
+ gDeferredMaterialProgram[i].addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredMaterialProgram[i].addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredMaterialProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+
+ if (use_sun_shadow)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ bool has_skin = i & 0x10;
+ gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
+ gDeferredMaterialProgram[i].mFeatures.hasTransport = true;
+ gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
+ gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
+ gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
+ gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
+ gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
+
+ if (has_skin)
+ {
+ gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
+ gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+
+ success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[i]);
+
+ gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
+
+ 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].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
+
+ gDeferredMaterialWaterProgram[i].clearPermutations();
+
+ bool has_normal_map = (i & 0x8) > 0;
+ bool has_specular_map = (i & 0x4) > 0;
+
+ if (has_normal_map)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", "1");
+ }
+
+ if (has_specular_map)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
+ }
+
+ gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (use_sun_shadow)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ bool has_skin = i & 0x10;
+ if (has_skin)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");
+ }
+ gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
+
+ if (ambient_kill)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredMaterialWaterProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.calculatesAtmospherics = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true;
+
+ gDeferredMaterialWaterProgram[i].mFeatures.hasTransport = true;
+ gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = use_sun_shadow;
+
+ if (has_skin)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+
+ success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
+ llassert(success);
}
}
@@ -1426,9 +1684,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTreeProgram.createShader(NULL, NULL);
}
@@ -1436,44 +1695,95 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
+ gDeferredImpostorProgram.mFeatures.hasSrgb = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredImpostorProgram.createShader(NULL, NULL);
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredImpostorProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
- {
+ {
gDeferredLightProgram.mName = "Deferred Light Shader";
+ gDeferredLightProgram.mFeatures.isDeferred = true;
+ gDeferredLightProgram.mFeatures.hasShadows = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ gDeferredLightProgram.clearPermutations();
+
+ if (ambient_kill)
+ {
+ gDeferredLightProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredLightProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
success = gDeferredLightProgram.createShader(NULL, NULL);
+ llassert(success);
}
for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
{
- if (success)
- {
+ if (success)
+ {
gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mFeatures.isDeferred = true;
+ gDeferredMultiLightProgram[i].mFeatures.hasShadows = true;
+ gDeferredMultiLightProgram[i].mFeatures.hasSrgb = true;
+
+ 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].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+
+ if (ambient_kill)
+ {
+ gDeferredMultiLightProgram[i].addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredMultiLightProgram[i].addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredMultiLightProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+ llassert(success);
}
}
@@ -1481,22 +1791,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
gDeferredSpotLightProgram.mShaderFiles.clear();
+ gDeferredSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredSpotLightProgram.mFeatures.isDeferred = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ if (ambient_kill)
+ {
+ gDeferredSpotLightProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredSpotLightProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredSpotLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
+ gDeferredMultiSpotLightProgram.mFeatures.hasSrgb = true;
+ gDeferredMultiSpotLightProgram.mFeatures.isDeferred = true;
+ gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
+
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ if (local_light_kill)
+ {
+ gDeferredMultiSpotLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1504,37 +1846,48 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
std::string fragment;
std::string vertex = "deferred/sunLightV.glsl";
- if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
- {
- fragment = "deferred/sunLightSSAOF.glsl";
- }
- else
- {
- fragment = "deferred/sunLightF.glsl";
- if (mVertexShaderLevel[SHADER_DEFERRED] == 1)
- { //no shadows, no SSAO, no frag coord
- vertex = "deferred/sunLightNoFragCoordV.glsl";
- }
- }
-
- gDeferredSunProgram.mName = "Deferred Sun Shader";
+ bool use_ao = gSavedSettings.getBOOL("RenderDeferredSSAO");
+
+ if (use_ao)
+ {
+ fragment = "deferred/sunLightSSAOF.glsl";
+ }
+ else
+ {
+ fragment = "deferred/sunLightF.glsl";
+ if (mShaderLevel[SHADER_DEFERRED] == 1)
+ { //no shadows, no SSAO, no frag coord
+ vertex = "deferred/sunLightNoFragCoordV.glsl";
+ }
+ }
+
+ gDeferredSunProgram.mName = "Deferred Sun Shader";
+ gDeferredSunProgram.mFeatures.isDeferred = true;
+ gDeferredSunProgram.mFeatures.hasShadows = true;
+ gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
+
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSunProgram.createShader(NULL, NULL);
+ success = gDeferredSunProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredBlurLightProgram.mName = "Deferred Blur Light Shader";
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1545,63 +1898,105 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
- {
- gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
-
- gDeferredAlphaProgram.mShaderFiles.clear();
- gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
- gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
- gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredAlphaProgram.mFeatures.hasTransport = true;
+ gDeferredAlphaProgram.mFeatures.hasShadows = use_sun_shadow;
+
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+
+ gDeferredAlphaProgram.mShaderFiles.clear();
+ gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredAlphaProgram.clearPermutations();
+ gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
+ if (use_sun_shadow)
+ {
+ gDeferredAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ gDeferredAlphaProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+
+ // Hack
+ gDeferredAlphaProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaProgram.mFeatures.hasLighting = true;
+ }
- success = gDeferredAlphaProgram.createShader(NULL, NULL);
-
- // Hack
- gDeferredAlphaProgram.mFeatures.calculatesLighting = true;
- gDeferredAlphaProgram.mFeatures.hasLighting = true;
- }
-
- if (success)
- {
- gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader";
+ if (success)
+ {
+ gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader";
+// Begin Hack
gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
+
+ gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true;
gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
- gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
- {
- gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true;
+ gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow;
- gDeferredAlphaImpostorProgram.mShaderFiles.clear();
- gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
- gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
- gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
- gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAlphaImpostorProgram.mShaderFiles.clear();
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
+ gDeferredAlphaImpostorProgram.clearPermutations();
+ gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
- // Hack
- gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
- gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
- }
+ if (use_sun_shadow)
+ {
+ gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", "1");
+ }
+
+ gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
+ llassert(success);
+
+// End Hack
+ gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
+ }
if (success)
{
@@ -1610,7 +2005,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
+ gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true;
+ gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasGamma = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasTransport = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
{
gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
}
@@ -1622,13 +2026,34 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaWaterProgram.mShaderFiles.clear();
gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredAlphaWaterProgram.clearPermutations();
gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
- gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
- gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ if (use_sun_shadow)
+ {
+ gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ gDeferredAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+ gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
+ llassert(success);
// Hack
gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true;
@@ -1642,11 +2067,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
gDeferredAvatarEyesProgram.mFeatures.hasTransport = true;
gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1655,12 +2085,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightProgram.mFeatures.hasGamma = true;
gDeferredFullbrightProgram.mFeatures.hasTransport = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1669,13 +2101,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
+ 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.addPermutation("HAS_ALPHA_MASK","1");
- gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1684,14 +2118,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1700,59 +2137,71 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader";
gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true;
gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true;
gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true;
gDeferredSkinnedFullbrightProgram.mShaderFiles.clear();
gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true;
gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true;
gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasSrgb = true;
gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear();
gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1765,8 +2214,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredEmissiveProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1776,11 +2226,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredWaterProgram.mFeatures.hasGamma = true;
gDeferredWaterProgram.mFeatures.hasTransport = true;
+ gDeferredWaterProgram.mFeatures.encodesNormal = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1788,23 +2243,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
// load water shader
gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredUnderWaterProgram.mFeatures.hasWaterFog = true;
gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
+ gDeferredUnderWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredUnderWaterProgram.mFeatures.encodesNormal = true;
+ //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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredSoftenProgram.mName = "Deferred Soften Shader";
gDeferredSoftenProgram.mShaderFiles.clear();
+ gDeferredSoftenProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenProgram.mFeatures.hasTransport = true;
+ gDeferredSoftenProgram.mFeatures.hasGamma = true;
+ gDeferredSoftenProgram.mFeatures.isDeferred = true;
+ gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ if (ambient_kill)
+ {
+ gDeferredSoftenProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredSoftenProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredSoftenProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
@@ -1812,6 +2298,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
success = gDeferredSoftenProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1821,9 +2308,33 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSoftenWaterProgram.clearPermutations();
+ gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredSoftenWaterProgram.mFeatures.hasWaterFog = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasTransport = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
+ gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
+ gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+
+ if (ambient_kill)
+ {
+ gDeferredSoftenWaterProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredSoftenWaterProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredSoftenWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
@@ -1831,55 +2342,98 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredShadowProgram.mName = "Deferred Shadow Shader";
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
success = gDeferredShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+ 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));
- gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
+ gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader";
+ 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.clearPermutations();
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
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));
- gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
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));
- gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
- if (success)
+ if (success)
{
gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
@@ -1887,8 +2441,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1899,23 +2454,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader";
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));
- gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
-
- if (success)
+
+ if (success)
{
gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
@@ -1923,8 +2484,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1935,29 +2497,70 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
- gTerrainProgram.mName = "Deferred Terrain Shader";
+ gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
+ gDeferredTerrainProgram.mFeatures.encodesNormal = true;
+ gDeferredTerrainProgram.mFeatures.hasSrgb = true;
+ gDeferredTerrainProgram.mFeatures.calculatesLighting = false;
+ gDeferredTerrainProgram.mFeatures.hasLighting = false;
+ gDeferredTerrainProgram.mFeatures.isAlphaLighting = true;
+ gDeferredTerrainProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredTerrainProgram.mFeatures.hasWaterFog = true;
+ gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
+ gDeferredTerrainProgram.mFeatures.hasGamma = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredTerrainProgram.createShader(NULL, NULL);
+ gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredTerrainProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredTerrainWaterProgram.mName = "Deferred Terrain Underwater Shader";
+ gDeferredTerrainWaterProgram.mFeatures.encodesNormal = true;
+ gDeferredTerrainWaterProgram.mFeatures.hasSrgb = true;
+ gDeferredTerrainWaterProgram.mFeatures.calculatesLighting = false;
+ gDeferredTerrainWaterProgram.mFeatures.hasLighting = false;
+ gDeferredTerrainWaterProgram.mFeatures.isAlphaLighting = true;
+ gDeferredTerrainWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ gDeferredTerrainWaterProgram.mFeatures.hasWaterFog = true;
+ gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true;
+ gDeferredTerrainWaterProgram.mFeatures.hasGamma = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
+ success = gDeferredTerrainWaterProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredAvatarProgram.mName = "Avatar Shader";
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -1968,15 +2571,45 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true;
+ gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasShadows = 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_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredAvatarAlphaProgram.clearPermutations();
gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
- gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ if (use_sun_shadow)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ }
+
+ if (ambient_kill)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("AMBIENT_KILL", "1");
+ }
+
+ if (sunlight_kill)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ gDeferredAvatarAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+ gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
@@ -1985,95 +2618,160 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gFXAAProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredCoFProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
- //gWLSkyProgram.mFeatures.hasGamma = true;
gDeferredWLSkyProgram.mShaderFiles.clear();
+ gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLSkyProgram.mFeatures.hasTransport = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+
success = gDeferredWLSkyProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
gDeferredWLCloudProgram.mShaderFiles.clear();
+ gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLCloudProgram.mFeatures.hasTransport = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLCloudProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
{
+ gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
+ gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLSunProgram.mFeatures.hasTransport = true;
+ gDeferredWLSunProgram.mFeatures.hasGamma = true;
+ gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLSunProgram.mFeatures.isFullbright = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gDeferredWLSunProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredWLMoonProgram.mName = "Deferred Windlight Moon Program";
+ gDeferredWLMoonProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredWLMoonProgram.mFeatures.hasTransport = true;
+ gDeferredWLMoonProgram.mFeatures.hasGamma = true;
+ gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
+ gDeferredWLMoonProgram.mFeatures.hasSrgb = true;
+ gDeferredWLMoonProgram.mFeatures.isFullbright = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gDeferredWLMoonProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredStarProgram.createShader(NULL, NULL);
+ llassert(success);
}
if (success)
@@ -2082,7 +2780,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gNormalMapGenProgram.createShader(NULL, NULL);
}
@@ -2094,7 +2792,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_OBJECT] == 0)
+ if (mShaderLevel[SHADER_OBJECT] == 0)
{
gObjectShinyProgram.unload();
gObjectFullbrightShinyProgram.unload();
@@ -2155,12 +2853,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true;
gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true;
gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true;
+ gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true; // Fix for MAINT-8836
gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleNonIndexedProgram.mShaderFiles.clear();
gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2176,7 +2874,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
}
@@ -2193,7 +2891,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear();
gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL);
}
@@ -2210,7 +2908,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);
}
@@ -2228,7 +2926,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2245,7 +2943,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
}
@@ -2263,7 +2961,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
}
@@ -2280,7 +2978,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
}
@@ -2298,7 +2996,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gTreeProgram.createShader(NULL, NULL);
}
@@ -2315,7 +3013,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gTreeWaterProgram.createShader(NULL, NULL);
}
@@ -2331,7 +3029,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNonIndexedProgram.mShaderFiles.clear();
gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2343,10 +3041,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
+ gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true;
gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear();
gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL);
}
@@ -2359,10 +3058,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true;
gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true;
gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true;
+ gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true;
gObjectEmissiveNonIndexedProgram.mShaderFiles.clear();
gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2377,7 +3077,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear();
gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL);
}
@@ -2389,11 +3089,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true;
gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true;
gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);
}
@@ -2408,7 +3109,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);
}
@@ -2425,7 +3126,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyNonIndexedProgram.mShaderFiles.clear();
gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2441,12 +3142,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear();
gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);
}
- if (success)
+ if (success)
{
gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader";
gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
@@ -2458,7 +3159,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear();
gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);
}
@@ -2475,7 +3176,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear();
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);
}
@@ -2484,10 +3185,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
{
gImpostorProgram.mName = "Impostor Shader";
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gImpostorProgram.createShader(NULL, NULL);
}
@@ -2504,7 +3206,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectPreviewProgram.createShader(NULL, NULL);
gObjectPreviewProgram.mFeatures.hasLighting = true;
}
@@ -2521,7 +3223,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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 = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleProgram.createShader(NULL, NULL);
}
@@ -2541,7 +3243,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);
}
@@ -2558,7 +3260,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
}
@@ -2572,10 +3274,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectBumpProgram.mFeatures.hasAtmospherics = true;
gObjectBumpProgram.mFeatures.hasLighting = true;
gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/
+ 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 = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectBumpProgram.createShader(NULL, NULL);
if (success)
{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
@@ -2600,7 +3303,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -2617,7 +3320,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -2629,11 +3332,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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 = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightProgram.createShader(NULL, NULL);
}
@@ -2648,7 +3352,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
}
@@ -2660,11 +3364,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveProgram.mFeatures.hasGamma = true;
gObjectEmissiveProgram.mFeatures.hasTransport = true;
gObjectEmissiveProgram.mFeatures.isFullbright = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectEmissiveProgram.createShader(NULL, NULL);
}
@@ -2679,7 +3384,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectEmissiveWaterProgram.createShader(NULL, NULL);
}
@@ -2692,11 +3397,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true;
gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true;
+ 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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -2712,7 +3418,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -2729,7 +3435,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectShinyProgram.createShader(NULL, NULL);
}
@@ -2745,7 +3451,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectShinyWaterProgram.createShader(NULL, NULL);
}
@@ -2762,7 +3468,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
@@ -2779,12 +3485,12 @@ BOOL LLViewerShaderMgr::loadShadersObject()
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 = mVertexShaderLevel[SHADER_OBJECT];
+ gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
}
- if (mVertexShaderLevel[SHADER_AVATAR] > 0)
+ if (mShaderLevel[SHADER_AVATAR] > 0)
{ //load hardware skinned attachment shaders
if (success)
{
@@ -2800,7 +3506,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleProgram.mShaderFiles.clear();
gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL);
}
@@ -2814,10 +3520,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;
+ gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true;
gSkinnedObjectFullbrightProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL);
}
@@ -2830,10 +3537,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true;
gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true;
+ gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true;
gSkinnedObjectEmissiveProgram.mShaderFiles.clear();
gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectEmissiveProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL);
}
@@ -2850,7 +3558,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear();
gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL);
}
@@ -2868,7 +3576,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
@@ -2886,7 +3594,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);
}
@@ -2907,7 +3615,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL);
}
@@ -2926,7 +3634,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL);
}
@@ -2946,7 +3654,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
}
@@ -2966,14 +3674,14 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear();
gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);
}
}
if( !success )
{
- mVertexShaderLevel[SHADER_OBJECT] = 0;
+ mShaderLevel[SHADER_OBJECT] = 0;
return FALSE;
}
@@ -2984,7 +3692,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ if (mShaderLevel[SHADER_AVATAR] == 0)
{
gAvatarProgram.unload();
gAvatarWaterProgram.unload();
@@ -3007,7 +3715,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
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.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
+ gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarProgram.createShader(NULL, NULL);
if (success)
@@ -3025,15 +3733,15 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
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));
// Note: no cloth under water:
- gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);
+ gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1);
gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gAvatarWaterProgram.createShader(NULL, NULL);
}
/// Keep track of avatar levels
- if (gAvatarProgram.mShaderLevel != mVertexShaderLevel[SHADER_AVATAR])
+ if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
{
- mMaxAvatarShaderLevel = mVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
+ mMaxAvatarShaderLevel = mShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
}
}
@@ -3045,7 +3753,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
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.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
+ gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarPickProgram.createShader(NULL, NULL);
}
@@ -3063,13 +3771,13 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
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.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
+ gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarEyeballProgram.createShader(NULL, NULL);
}
if( !success )
{
- mVertexShaderLevel[SHADER_AVATAR] = 0;
+ mShaderLevel[SHADER_AVATAR] = 0;
mMaxAvatarShaderLevel = 0;
return FALSE;
}
@@ -3081,7 +3789,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_INTERFACE] == 0)
+ if (mShaderLevel[SHADER_INTERFACE] == 0)
{
gHighlightProgram.unload();
return TRUE;
@@ -3093,7 +3801,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightProgram.createShader(NULL, NULL);
}
@@ -3103,7 +3811,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -3113,7 +3821,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -3123,7 +3831,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gUIProgram.createShader(NULL, NULL);
}
@@ -3133,7 +3841,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingProgram.createShader(NULL, NULL);
}
@@ -3143,7 +3851,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
}
@@ -3153,7 +3861,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCustomAlphaProgram.createShader(NULL, NULL);
}
@@ -3163,7 +3871,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSplatTextureRectProgram.createShader(NULL, NULL);
if (success)
{
@@ -3179,7 +3887,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineProgram.createShader(NULL, NULL);
if (success)
{
@@ -3196,7 +3904,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
if (success)
{
@@ -3214,7 +3922,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureAddProgram.createShader(NULL, NULL);
if (success)
{
@@ -3231,7 +3939,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureCompareProgram.createShader(NULL, NULL);
if (success)
{
@@ -3248,7 +3956,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureFilterProgram.createShader(NULL, NULL);
if (success)
{
@@ -3264,7 +3972,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureNoColorProgram.createShader(NULL, NULL);
if (success)
{
@@ -3279,7 +3987,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSolidColorProgram.createShader(NULL, NULL);
if (success)
{
@@ -3295,7 +4003,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOcclusionProgram.createShader(NULL, NULL);
}
@@ -3305,7 +4013,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOcclusionCubeProgram.createShader(NULL, NULL);
}
@@ -3315,7 +4023,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDebugProgram.createShader(NULL, NULL);
}
@@ -3325,7 +4033,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gClipProgram.createShader(NULL, NULL);
}
@@ -3335,7 +4043,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthProgram.createShader(NULL, NULL);
}
@@ -3345,7 +4053,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gBenchmarkProgram.createShader(NULL, NULL);
}
@@ -3355,17 +4063,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
- success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- 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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
}
@@ -3375,13 +4073,13 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
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.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gAlphaMaskProgram.createShader(NULL, NULL);
}
if( !success )
{
- mVertexShaderLevel[SHADER_INTERFACE] = 0;
+ mShaderLevel[SHADER_INTERFACE] = 0;
return FALSE;
}
@@ -3392,36 +4090,80 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_WINDLIGHT] < 2)
+ if (mShaderLevel[SHADER_WINDLIGHT] < 2)
{
gWLSkyProgram.unload();
gWLCloudProgram.unload();
+ gWLSunProgram.unload();
+ gWLMoonProgram.unload();
return TRUE;
}
- if (success)
- {
- gWLSkyProgram.mName = "Windlight Sky Shader";
- //gWLSkyProgram.mFeatures.hasGamma = true;
- gWLSkyProgram.mShaderFiles.clear();
- 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.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];
- gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLSkyProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ gWLSkyProgram.mName = "Windlight Sky Shader";
+ gWLSkyProgram.mShaderFiles.clear();
+ gWLSkyProgram.mFeatures.calculatesAtmospherics = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
+ gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gWLSkyProgram.createShader(NULL, NULL);
+ }
- if (success)
- {
- gWLCloudProgram.mName = "Windlight Cloud Program";
- //gWLCloudProgram.mFeatures.hasGamma = true;
- gWLCloudProgram.mShaderFiles.clear();
- 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.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];
- gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLCloudProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ gWLCloudProgram.mName = "Windlight Cloud Program";
+ gWLCloudProgram.mShaderFiles.clear();
+ gWLCloudProgram.mFeatures.calculatesAtmospherics = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
+ gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gWLCloudProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gWLSunProgram.mName = "Windlight Sun Program";
+ gWLSunProgram.mShaderFiles.clear();
+ gWLSunProgram.mFeatures.calculatesAtmospherics = true;
+ gWLSunProgram.mFeatures.hasTransport = true;
+ gWLSunProgram.mFeatures.hasGamma = true;
+ gWLSunProgram.mFeatures.hasAtmospherics = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
+ gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gWLSunProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gWLMoonProgram.mName = "Windlight Moon Program";
+ gWLMoonProgram.mShaderFiles.clear();
+ gWLMoonProgram.mFeatures.calculatesAtmospherics = true;
+ gWLMoonProgram.mFeatures.hasTransport = true;
+ gWLMoonProgram.mFeatures.hasGamma = true;
+ gWLMoonProgram.mFeatures.hasAtmospherics = true;
+ 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.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
+ gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ success = gWLMoonProgram.createShader(NULL, NULL);
+ }
return success;
}
@@ -3430,7 +4172,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
{
BOOL success = TRUE;
- if (mVertexShaderLevel[SHADER_TRANSFORM] < 1)
+ if (mShaderLevel[SHADER_TRANSFORM] < 1)
{
gTransformPositionProgram.unload();
gTransformTexCoordProgram.unload();
@@ -3442,10 +4184,10 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
if (success)
{
- gTransformPositionProgram.mName = "Position Transform Shader";
+ gTransformPositionProgram.mName = "Position Transform Shader";
gTransformPositionProgram.mShaderFiles.clear();
gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
"position_out",
@@ -3460,7 +4202,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
gTransformTexCoordProgram.mShaderFiles.clear();
gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
"texcoord_out",
@@ -3474,7 +4216,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
gTransformNormalProgram.mName = "Normal Transform Shader";
gTransformNormalProgram.mShaderFiles.clear();
gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
"normal_out",
@@ -3488,7 +4230,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
gTransformColorProgram.mName = "Color Transform Shader";
gTransformColorProgram.mShaderFiles.clear();
gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
"color_out",
@@ -3502,7 +4244,7 @@ BOOL LLViewerShaderMgr::loadTransformShaders()
gTransformTangentProgram.mName = "Binormal Transform Shader";
gTransformTangentProgram.mShaderFiles.clear();
gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+ gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
const char* varyings[] = {
"tangent_out",
@@ -3522,8 +4264,7 @@ std::string LLViewerShaderMgr::getShaderDirPrefix(void)
void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
{
- LLWLParamManager::getInstance()->updateShaderUniforms(shader);
- LLWaterParamManager::getInstance()->updateShaderUniforms(shader);
+ LLEnvironment::instance().updateShaderUniforms(shader);
}
LLViewerShaderMgr::shader_iter LLViewerShaderMgr::beginShaders() const
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 9edaa97e57..081221f15b 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -48,7 +48,7 @@ public:
void initAttribsAndUniforms(void);
void setShaders();
void unloadShaders();
- S32 getVertexShaderLevel(S32 type);
+ S32 getShaderLevel(S32 type);
BOOL loadBasicShaders();
BOOL loadShadersEffects();
BOOL loadShadersDeferred();
@@ -60,7 +60,7 @@ public:
BOOL loadShadersWindLight();
BOOL loadTransformShaders();
- std::vector<S32> mVertexShaderLevel;
+ std::vector<S32> mShaderLevel;
S32 mMaxAvatarShaderLevel;
enum EShaderClass
@@ -129,24 +129,6 @@ public:
/* virtual */ void updateShaderUniforms(LLGLSLShader * shader);
private:
-
- std::vector<std::string> mShinyUniforms;
-
- //water parameters
- std::vector<std::string> mWaterUniforms;
-
- std::vector<std::string> mWLUniforms;
-
- //terrain parameters
- std::vector<std::string> mTerrainUniforms;
-
- //glow parameters
- std::vector<std::string> mGlowUniforms;
-
- std::vector<std::string> mGlowExtractUniforms;
-
- std::vector<std::string> mAvatarUniforms;
-
// the list of shaders we need to propagate parameters to.
std::vector<LLGLSLShader *> mShaderList;
@@ -255,6 +237,7 @@ extern LLGLSLShader gSkinnedObjectShinySimpleWaterProgram;
extern LLGLSLShader gTerrainProgram;
extern LLGLSLShader gTerrainWaterProgram;
extern LLGLSLShader gWaterProgram;
+extern LLGLSLShader gWaterEdgeProgram;
extern LLGLSLShader gUnderWaterProgram;
extern LLGLSLShader gGlowProgram;
extern LLGLSLShader gGlowExtractProgram;
@@ -281,6 +264,8 @@ extern LLGLSLShader gImpostorProgram;
// WindLight shader handles
extern LLGLSLShader gWLSkyProgram;
extern LLGLSLShader gWLCloudProgram;
+extern LLGLSLShader gWLSunProgram;
+extern LLGLSLShader gWLMoonProgram;
// Post Process Shaders
extern LLGLSLShader gPostColorFilterProgram;
@@ -301,6 +286,7 @@ extern LLGLSLShader gDeferredSkinnedBumpProgram;
extern LLGLSLShader gDeferredSkinnedAlphaProgram;
extern LLGLSLShader gDeferredBumpProgram;
extern LLGLSLShader gDeferredTerrainProgram;
+extern LLGLSLShader gDeferredTerrainWaterProgram;
extern LLGLSLShader gDeferredTreeProgram;
extern LLGLSLShader gDeferredTreeShadowProgram;
extern LLGLSLShader gDeferredLightProgram;
@@ -315,6 +301,7 @@ extern LLGLSLShader gDeferredSoftenWaterProgram;
extern LLGLSLShader gDeferredShadowProgram;
extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
+extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
extern LLGLSLShader gDeferredDoFCombineProgram;
@@ -339,6 +326,8 @@ extern LLGLSLShader gDeferredAvatarEyesProgram;
extern LLGLSLShader gDeferredAvatarAlphaProgram;
extern LLGLSLShader gDeferredWLSkyProgram;
extern LLGLSLShader gDeferredWLCloudProgram;
+extern LLGLSLShader gDeferredWLSunProgram;
+extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 15b2ac8acf..314c1a1f1e 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -55,14 +55,15 @@
#include "llviewerregion.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
-#include "llviewerwindow.h" // *TODO: remove, only used for width/height
#include "llworld.h"
#include "llfeaturemanager.h"
#include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llcorehttputil.h"
#include "llvoicevivox.h"
+#include "lluiusage.h"
namespace LLStatViewer
{
@@ -359,16 +360,19 @@ void update_statistics()
record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Sort Draw State")));
record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Render Geometry")));
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
- if (cdp)
+ if (gAgent.getRegion() && isAgentAvatarValid())
{
- sample(LLStatViewer::SIM_PING, F64Milliseconds (cdp->getPingDelay()));
- gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
- gSimPingCount++;
- }
- else
- {
- sample(LLStatViewer::SIM_PING, U32Seconds(10));
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
+ if (cdp)
+ {
+ sample(LLStatViewer::SIM_PING, F64Milliseconds(cdp->getPingDelay()));
+ gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
+ gSimPingCount++;
+ }
+ else
+ {
+ sample(LLStatViewer::SIM_PING, U32Seconds(10));
+ }
}
if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS))
@@ -423,7 +427,7 @@ void update_statistics()
* If you move stats around here, make the corresponding changes in
* those locations, too.
*/
-void send_stats()
+void send_viewer_stats(bool include_preferences)
{
// IW 9/23/02 I elected not to move this into LLViewerStats
// because it depends on too many viewer.cpp globals.
@@ -470,7 +474,7 @@ void send_stats()
// send fps only for time app spends in foreground
agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
- agent["version"] = LLVersionInfo::getChannelAndVersion();
+ agent["version"] = LLVersionInfo::instance().getChannelAndVersion();
std::string language = LLUI::getLanguage();
agent["language"] = language;
@@ -511,6 +515,8 @@ void send_stats()
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
system["opengl_version"] = gGLManager.mGLVersionString;
+ gGLManager.asLLSD(system["gl"]);
+
S32 shader_level = 0;
if (LLPipeline::sRenderDeferred)
{
@@ -570,7 +576,10 @@ void send_stats()
fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
+ fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing();
+ body["ui"] = LLUIUsage::instance().asLLSD();
+
body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read();
// Misc stats, two strings and two ints
@@ -579,29 +588,61 @@ void send_stats()
// If the current revision is recent, ping the previous author before overriding
LLSD &misc = body["stats"]["misc"];
- // Screen size so the UI team can figure out how big the widgets
- // appear and use a "typical" size for end user tests.
-
- S32 window_width = gViewerWindow->getWindowWidthRaw();
- S32 window_height = gViewerWindow->getWindowHeightRaw();
- S32 window_size = (window_width * window_height) / 1024;
- misc["string_1"] = llformat("%d", window_size);
- misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds.value());
-
- F32 unbaked_time = LLVOAvatar::sUnbakedTime * 1000.f / gFrameTimeSeconds;
- misc["int_1"] = LLSD::Integer(unbaked_time); // Steve: 1.22
- F32 grey_time = LLVOAvatar::sGreyTime * 1000.f / gFrameTimeSeconds;
- misc["int_2"] = LLSD::Integer(grey_time); // Steve: 1.22
-
- LL_INFOS() << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << LL_ENDL;
+#ifdef LL_WINDOWS
+ // Probe for Vulkan capability (Dave Houlton 05/2020)
+ //
+ // Check for presense of a Vulkan loader dll, as a proxy for a Vulkan-capable gpu.
+ // False-positives and false-negatives are possible, but unlikely. We'll get a good
+ // approximation of Vulkan capability within current user systems from this. More
+ // detailed information on versions and extensions can come later.
+ static bool vulkan_oneshot = false;
+ static bool vulkan_detected = false;
+
+ if (!vulkan_oneshot)
+ {
+ HMODULE vulkan_loader = LoadLibraryExA("vulkan-1.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
+ if (NULL != vulkan_loader)
+ {
+ vulkan_detected = true;
+ FreeLibrary(vulkan_loader);
+ }
+ vulkan_oneshot = true;
+ }
+
+ misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected");
+
+#else
+ misc["string_1"] = llformat("Unused");
+#endif // LL_WINDOWS
+
+ misc["string_2"] = llformat("Unused");
+ misc["int_1"] = LLSD::Integer(0);
+ misc["int_2"] = LLSD::Integer(0);
+
+ LL_INFOS() << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << LL_ENDL;
LL_INFOS() << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << LL_ENDL;
body["DisplayNamesEnabled"] = gSavedSettings.getBOOL("UseDisplayNames");
body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames");
-
+
+ // Preferences
+ if (include_preferences)
+ {
+ bool diffs_only = true; // only log preferences that differ from default
+ body["preferences"]["settings"] = gSavedSettings.asLLSD(diffs_only);
+ body["preferences"]["settings_per_account"] = gSavedPerAccountSettings.asLLSD(diffs_only);
+ }
+
body["MinimalSkin"] = false;
+
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
+ if (debugLoggingEnabled("LogViewerStatsPacket"))
+ {
+ std::string filename("viewer_stats_packet.xml");
+ llofstream of(filename.c_str());
+ LLSDSerialize::toPrettyXML(body,of);
+ }
// The session ID token must never appear in logs
body["session_id"] = gAgentSessionID;
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index d8d92d61d3..04870e0c26 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -294,7 +294,7 @@ static const F32 SEND_STATS_PERIOD = 300.0f;
// The following are from (older?) statistics code found in appviewer.
void update_statistics();
-void send_stats();
+void send_viewer_stats(bool include_preferences);
extern LLFrameTimer gTextureTimer;
extern U32Bytes gTotalTextureData;
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
index 7f7d190b92..c501dd0035 100644
--- a/indra/newview/llviewertexlayer.cpp
+++ b/indra/newview/llviewertexlayer.cpp
@@ -54,7 +54,7 @@ LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner,
S32 width, S32 height) :
// ORDER_LAST => must render these after the hints are created.
LLTexLayerSetBuffer(owner),
- LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
+ LLViewerDynamicTexture(width, height, 4, LLViewerDynamicTexture::ORDER_LAST, FALSE),
mNeedsUpdate(TRUE),
mNumLowresUpdates(0)
{
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
index 027ae255ec..dec7f0ddfc 100644
--- a/indra/newview/llviewertexlayer.h
+++ b/indra/newview/llviewertexlayer.h
@@ -111,7 +111,7 @@ protected:
// Pass these along for tex layer rendering.
virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); }
virtual void postRender(BOOL success) { postRenderTexLayerSet(success); }
- virtual BOOL render() { return renderTexLayerSet(); }
+ virtual BOOL render() { return renderTexLayerSet(mBoundTarget); }
//--------------------------------------------------------------------
// Updates
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 0e181bf53d..e2de7ac825 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -31,6 +31,7 @@
#include "llagent.h"
#include "llaudioengine.h"
#include "llavataractions.h"
+#include "llenvironment.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
@@ -540,7 +541,9 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break;
case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break;
case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break;
- default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
+ case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break;
+ default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
+
}
return LLUI::getUIImage(img_name);
@@ -852,8 +855,18 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
if (getEnabled() && acceptsTextInput())
{
+ bool supported = false;
switch( cargo_type )
{
+ case DAD_SETTINGS:
+ {
+ supported = LLEnvironment::instance().isExtendedEnvironmentEnabled();
+ if (!supported && tooltip_msg.empty())
+ {
+ tooltip_msg.assign(LLTrans::getString("TooltipNotecardNotAllowedTypeDrop"));
+ }
+ break;
+ }
case DAD_CALLINGCARD:
case DAD_TEXTURE:
case DAD_SOUND:
@@ -867,52 +880,50 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_GESTURE:
case DAD_MESH:
{
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
- if( item && allowsEmbeddedItems() )
+ supported = true;
+ break;
+ }
+
+ default:
+ supported = false;
+ break;
+ }
+
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+ if (item && allowsEmbeddedItems() && supported)
+ {
+ U32 mask_next = item->getPermissions().getMaskNextOwner();
+ if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
+ {
+ if( drop )
{
- U32 mask_next = item->getPermissions().getMaskNextOwner();
- if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
- {
- if( drop )
- {
- deselect();
- S32 old_cursor = mCursorPos;
- setCursorAtLocalPos( x, y, TRUE );
- S32 insert_pos = mCursorPos;
- setCursorPos(old_cursor);
- BOOL inserted = insertEmbeddedItem( insert_pos, item );
- if( inserted && (old_cursor > mCursorPos) )
- {
- setCursorPos(mCursorPos + 1);
- }
-
- needsReflow();
-
- }
- *accept = ACCEPT_YES_COPY_MULTI;
- }
- else
+ deselect();
+ S32 old_cursor = mCursorPos;
+ setCursorAtLocalPos( x, y, TRUE );
+ S32 insert_pos = mCursorPos;
+ setCursorPos(old_cursor);
+ BOOL inserted = insertEmbeddedItem( insert_pos, item );
+ if( inserted && (old_cursor > mCursorPos) )
{
- *accept = ACCEPT_NO;
- if (tooltip_msg.empty())
- {
- // *TODO: Translate
- tooltip_msg.assign("Only items with unrestricted\n"
- "'next owner' permissions \n"
- "can be attached to notecards.");
- }
+ setCursorPos(mCursorPos + 1);
}
+
+ needsReflow();
}
- else
+ *accept = ACCEPT_YES_COPY_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ if (tooltip_msg.empty())
{
- *accept = ACCEPT_NO;
+ tooltip_msg.assign(LLTrans::getString("TooltipNotecardOwnerRestrictedDrop"));
}
- break;
}
-
- default:
+ }
+ else
+ {
*accept = ACCEPT_NO;
- break;
}
}
else
@@ -1112,7 +1123,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwch
case LLAssetType::AT_CALLINGCARD:
openEmbeddedCallingcard( item, wc );
return TRUE;
-
+ case LLAssetType::AT_SETTINGS:
+ openEmbeddedSetting(item, wc);
+ return TRUE;
case LLAssetType::AT_NOTECARD:
case LLAssetType::AT_LSL_TEXT:
case LLAssetType::AT_CLOTHING:
@@ -1187,6 +1200,18 @@ void LLViewerTextEditor::openEmbeddedCallingcard( LLInventoryItem* item, llwchar
}
}
+void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc)
+{
+ if (LLEnvironment::instance().isInventoryEnabled())
+ {
+ showCopyToInvDialog(item, wc);
+ }
+ else
+ {
+ LLNotificationsUtil::add("NoEnvironmentSettings");
+ }
+}
+
void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
{
LLSD payload;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index 44f104dde1..a6d7fef409 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -107,6 +107,7 @@ private:
void openEmbeddedSound( LLInventoryItem* item, llwchar wc );
void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
+ void openEmbeddedSetting(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 305f891a86..ca01bb46aa 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -98,8 +98,8 @@ const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez;
const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
const S32 DEFAULT_ICON_DIMENTIONS = 32;
-S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
-S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
+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;
@@ -1238,6 +1238,8 @@ void LLViewerFetchedTexture::loadFromFastCache()
{
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
+ // Shouldn't do anything usefull since texures in fast cache are 16x16,
+ // it is here in case fast cache changes.
S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
@@ -1485,7 +1487,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
mOrigWidth = mRawImage->getWidth();
mOrigHeight = mRawImage->getHeight();
-
+ // This is only safe because it's a local image and fetcher doesn't use raw data
+ // from local images, but this might become unsafe in case of changes to fetcher
if (mBoostLevel == BOOST_PREVIEW)
{
mRawImage->biasedScaleToPowerOfTwo(1024);
@@ -1541,6 +1544,26 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
+ if (mGLTexturep->getHasExplicitFormat())
+ {
+ LLGLenum format = mGLTexturep->getPrimaryFormat();
+ S8 components = mRawImage->getComponents();
+ if ((format == GL_RGBA && components < 4)
+ || (format == GL_RGB && components < 3))
+ {
+ LL_WARNS() << "Can't create a texture " << mID << ": invalid image format " << std::hex << format << " vs components " << (U32)components << LL_ENDL;
+ // Was expecting specific format but raw texture has insufficient components for
+ // such format, using such texture will result in crash or will display wrongly
+ // if we change format. Texture might be corrupted server side, so just set as
+ // missing and clear cashed texture (do not cause reload loop, will retry&recover
+ // during new session)
+ setIsMissingAsset();
+ destroyRawImage();
+ LLAppViewer::getTextureCache()->removeFromCache(mID);
+ return FALSE;
+ }
+ }
+
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
notifyAboutCreatingTexture();
@@ -1989,6 +2012,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (mRawImage.notNull()) sRawCount--;
if (mAuxRawImage.notNull()) sAuxCount--;
+ // keep in mind that fetcher still might need raw image, don't modify original
bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage,
mLastHttpGetStatus);
if (mRawImage.notNull()) sRawCount++;
@@ -2048,7 +2072,8 @@ bool LLViewerFetchedTexture::updateFetch()
if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
{
// scale oversized icon, no need to give more work to gl
- mRawImage->scale(expected_width, expected_height);
+ // since we got mRawImage from thread worker and image may be in use (ex: writing cache), make a copy
+ mRawImage = mRawImage->scaled(expected_width, expected_height);
}
}
@@ -3289,13 +3314,6 @@ void LLViewerLODTexture::processTextureStats()
{
mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
}
- else if(LLPipeline::sMemAllocationThrottled)//release memory of large textures by decrease their resolutions.
- {
- if(scaleDown())
- {
- mDesiredDiscardLevel = mCachedRawDiscardLevel;
- }
- }
}
bool LLViewerLODTexture::scaleDown()
@@ -3481,7 +3499,10 @@ BOOL LLViewerMediaTexture::findFaces()
U32 end = tex->getNumFaces(ch);
for(U32 i = 0; i < end; i++)
{
- mMediaFaceList.push_back((*face_list)[i]);
+ if ((*face_list)[i]->isMediaAllowed())
+ {
+ mMediaFaceList.push_back((*face_list)[i]);
+ }
}
}
}
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 7cbcc931b1..69568cc825 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -125,6 +125,8 @@ public:
virtual BOOL isMissingAsset() const ;
virtual void dump(); // debug info to LL_INFOS()
+ virtual bool isViewerMediaTexture() const { return false; }
+
/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
/*virtual*/ bool bindDebugImage(const S32 stage = 0) ;
/*virtual*/ void forceImmediateUpdate() ;
@@ -228,8 +230,8 @@ public:
static S8 sCameraMovingDiscardBias;
static F32 sCameraMovingBias;
static S32 sMaxSculptRez ;
- static S32 sMinLargeImageSize ;
- static S32 sMaxSmallImageSize ;
+ static U32 sMinLargeImageSize ;
+ static U32 sMaxSmallImageSize ;
static bool sFreezeImageUpdates;
static F32 sCurrentTime ;
@@ -579,6 +581,8 @@ public:
BOOL isPlaying() const {return mIsPlaying;}
void setMediaImpl() ;
+ virtual bool isViewerMediaTexture() const { return true; }
+
void initVirtualSize() ;
void invalidateMediaImpl() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 06524847d1..561319ca5d 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1385,8 +1385,6 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl
{
max_texmem = (S32Megabytes)128;
}
-
- LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL;
}
S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
@@ -1428,6 +1426,11 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
return; //listener will re-enter this function
}
+ if (gGLManager.mVRAM == 0)
+ {
+ LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL;
+ }
+
// TODO: set available resident texture mem based on use by other subsystems
// currently max(12MB, VRAM/4) assumed...
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 2d7a0f920f..9c4dfd1ca2 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -178,7 +178,7 @@ BOOL LLViewerWearable::isOldVersion() const
S32 te_count = 0;
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_count++;
if( !is_in_map(mTEMap, te ) )
@@ -230,7 +230,7 @@ BOOL LLViewerWearable::isDirty() const
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator current_iter = mTEMap.find(te);
if(current_iter != mTEMap.end())
@@ -276,7 +276,7 @@ void LLViewerWearable::setTexturesToDefaults()
{
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
LLUUID id = getDefaultTextureImageID((ETextureIndex) te);
LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
@@ -300,7 +300,7 @@ void LLViewerWearable::setTexturesToDefaults()
// virtual
LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture(index);
const std::string &default_image_name = texture_dict ? texture_dict->mDefaultImageName : "";
if (default_image_name == "")
{
@@ -331,7 +331,7 @@ void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
// Pull texture entries
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = mTEMap.find(te);
LLUUID image_id;
@@ -424,7 +424,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
for (S32 te = 0; te < TEX_NUM_INDICES; te++)
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = src->mTEMap.find(te);
LLUUID image_id;
@@ -463,8 +463,7 @@ void LLViewerWearable::revertValues()
{
LLWearable::revertValues();
-
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::findPanel("appearance"));
if( panel )
{
panel->updateScrollingPanelList();
@@ -480,7 +479,7 @@ void LLViewerWearable::saveValues()
{
LLWearable::saveValues();
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::findPanel("appearance"));
if( panel )
{
panel->updateScrollingPanelList();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c214984e1d..21985d5a8a 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -45,7 +45,8 @@
#include "llmeshrepository.h"
#include "llnotificationhandler.h"
#include "llpanellogin.h"
-#include "llviewerkeyboard.h"
+#include "llsetkeybinddialog.h"
+#include "llviewerinput.h"
#include "llviewermenu.h"
#include "llviewquery.h"
@@ -173,7 +174,7 @@
#include "llviewergesture.h"
#include "llviewertexturelist.h"
#include "llviewerinventory.h"
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
#include "llviewermedia.h"
#include "llviewermediafocus.h"
#include "llviewermenu.h"
@@ -313,6 +314,99 @@ RecordToChatConsole::RecordToChatConsole():
////////////////////////////////////////////////////////////////////////////
//
+// Print Utility
+//
+
+// Convert a normalized float (-1.0 <= x <= +1.0) to a fixed 1.4 format string:
+//
+// s#.####
+//
+// Where:
+// s sign character; space if x is positiv, minus if negative
+// # decimal digits
+//
+// This is similar to printf("%+.4f") except positive numbers are NOT cluttered with a leading '+' sign.
+// NOTE: This does NOT null terminate the output
+void normalized_float_to_string(const float x, char *out_str)
+{
+ static const unsigned char DECIMAL_BCD2[] =
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
+ };
+
+ int neg = (x < 0);
+ int rem = neg
+ ? (int)(x * -10000.)
+ : (int)(x * 10000.);
+
+ int d10 = rem % 100; rem /= 100;
+ int d32 = rem % 100; rem /= 100;
+
+ out_str[6] = '0' + ((DECIMAL_BCD2[ d10 ] >> 0) & 0xF);
+ out_str[5] = '0' + ((DECIMAL_BCD2[ d10 ] >> 4) & 0xF);
+ out_str[4] = '0' + ((DECIMAL_BCD2[ d32 ] >> 0) & 0xF);
+ out_str[3] = '0' + ((DECIMAL_BCD2[ d32 ] >> 4) & 0xF);
+ out_str[2] = '.';
+ out_str[1] = '0' + (rem & 1);
+ out_str[0] = " -"[neg]; // Could always show '+' for positive but this clutters up the common case
+}
+
+// normalized float
+// printf("%-.4f %-.4f %-.4f")
+// Params:
+// float &matrix_row[4]
+// int matrix_cell_index
+// string out_buffer (size 32)
+// Note: The buffer is assumed to be pre-filled with spaces
+#define MATRIX_ROW_N32_TO_STR(matrix_row, i, out_buffer) \
+ normalized_float_to_string(matrix_row[i+0], out_buffer + 0); \
+ normalized_float_to_string(matrix_row[i+1], out_buffer + 11); \
+ normalized_float_to_string(matrix_row[i+2], out_buffer + 22); \
+ out_buffer[31] = 0;
+
+
+// regular float
+// sprintf(buffer, "%-8.2f %-8.2f %-8.2f", matrix_row[i+0], matrix_row[i+1], matrix_row[i+2]);
+// Params:
+// float &matrix_row[4]
+// int matrix_cell_index
+// char out_buffer[32]
+// Note: The buffer is assumed to be pre-filled with spaces
+#define MATRIX_ROW_F32_TO_STR(matrix_row, i, out_buffer) { \
+ static const char *format[3] = { \
+ "%-8.2f" , /* 0 */ \
+ "> 99K ", /* 1 */ \
+ "< -99K " /* 2 */ \
+ }; \
+ \
+ F32 temp_0 = matrix_row[i+0]; \
+ F32 temp_1 = matrix_row[i+1]; \
+ F32 temp_2 = matrix_row[i+2]; \
+ \
+ U8 flag_0 = (((U8)(temp_0 < -99999.99)) << 1) | ((U8)(temp_0 > 99999.99)); \
+ U8 flag_1 = (((U8)(temp_1 < -99999.99)) << 1) | ((U8)(temp_1 > 99999.99)); \
+ U8 flag_2 = (((U8)(temp_2 < -99999.99)) << 1) | ((U8)(temp_2 > 99999.99)); \
+ \
+ if (temp_0 < 0.f) out_buffer[ 0] = '-'; \
+ if (temp_1 < 0.f) out_buffer[11] = '-'; \
+ if (temp_2 < 0.f) out_buffer[22] = '-'; \
+ \
+ sprintf(out_buffer+ 1,format[flag_0],fabsf(temp_0)); out_buffer[ 1+8] = ' '; \
+ sprintf(out_buffer+12,format[flag_1],fabsf(temp_1)); out_buffer[12+8] = ' '; \
+ sprintf(out_buffer+23,format[flag_2],fabsf(temp_2)); out_buffer[23+8] = 0 ; \
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
// LLDebugText
//
@@ -333,7 +427,11 @@ private:
typedef std::vector<Line> line_list_t;
line_list_t mLineList;
LLColor4 mTextColor;
-
+
+ LLColor4 mBackColor;
+ LLRect mBackRectCamera1;
+ LLRect mBackRectCamera2;
+
void addText(S32 x, S32 y, const std::string &text)
{
mLineList.push_back(Line(text, x, y));
@@ -346,6 +444,12 @@ public:
void update()
{
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ clearText();
+ return;
+ }
+
static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
std::string wind_vel_text;
@@ -360,6 +464,8 @@ public:
static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
static const std::string beacon_sound = LLTrans::getString("BeaconSound");
static const std::string beacon_media = LLTrans::getString("BeaconMedia");
+ static const std::string beacon_sun = LLTrans::getString("BeaconSun");
+ static const std::string beacon_moon = LLTrans::getString("BeaconMoon");
static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
// Draw the statistics in a light gray
@@ -367,11 +473,22 @@ public:
mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
// Draw stuff growing up from right lower corner of screen
- S32 xpos = mWindow->getWorldViewWidthScaled() - 400;
+ S32 x_right = mWindow->getWorldViewWidthScaled();
+ S32 xpos = x_right - 400;
xpos = llmax(xpos, 0);
S32 ypos = 64;
const S32 y_inc = 20;
+ // Camera matrix text is hard to see again a white background
+ // Add a dark background underneath the matrices for readability (contrast)
+ mBackRectCamera1.mLeft = xpos;
+ mBackRectCamera1.mRight = x_right;
+ mBackRectCamera1.mTop = -1;
+ mBackRectCamera1.mBottom = -1;
+ mBackRectCamera2 = mBackRectCamera1;
+
+ mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
+
clearText();
if (gSavedSettings.getBOOL("DebugShowTime"))
@@ -604,7 +721,7 @@ public:
addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
ypos += y_inc;
- addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize)));
+ addText(xpos, ypos, llformat("%d Render Calls", (U32)last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize)));
ypos += y_inc;
addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects()));
@@ -707,48 +824,45 @@ public:
}
if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
{
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
- ypos += y_inc;
+ char camera_lines[8][32];
+ memset(camera_lines, ' ', sizeof(camera_lines));
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11]));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7]));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3]));
- ypos += y_inc;
+ // Projection last column is always <0,0,-1.0001,0>
+ // Projection last row is always <0,0,-0.2>
+ mBackRectCamera1.mBottom = ypos - y_inc + 2;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop = ypos + 2;
+ MATRIX_ROW_N32_TO_STR(gGLProjection, 0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2;
addText(xpos, ypos, "Projection Matrix");
ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15]));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11]));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7]));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3]));
- ypos += y_inc;
+ // View last column is always <0,0,0,1>
+ MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2;
+ MATRIX_ROW_N32_TO_STR(gGLModelView, 0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc;
addText(xpos, ypos, "View Matrix");
ypos += y_inc;
}
// disable use of glReadPixels which messes up nVidia nSight graphics debugging
- if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
- {
- U8 color[4];
- LLCoordGL coord = gViewerWindow->getCurrentMouse();
- glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color);
- addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
- ypos += y_inc;
- }
+ if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
+ {
+ U8 color[4];
+ LLCoordGL coord = gViewerWindow->getCurrentMouse();
- // only display these messages if we are actually rendering beacons at this moment
+ // Convert x,y to raw pixel coords
+ S32 x_raw = llround(coord.mX * gViewerWindow->getWindowWidthRaw() / (F32) gViewerWindow->getWindowWidthScaled());
+ S32 y_raw = llround(coord.mY * gViewerWindow->getWindowHeightRaw() / (F32) gViewerWindow->getWindowHeightScaled());
+
+ glReadPixels(x_raw, y_raw, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
+ addText(xpos, ypos, llformat("Pixel <%1d, %1d> R:%1d G:%1d B:%1d A:%1d", x_raw, y_raw, color[0], color[1], color[2], color[3]));
+ ypos += y_inc;
+ }
+
+ // only display these messages if we are actually rendering beacons at this moment
if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
{
if (LLPipeline::getRenderMOAPBeacons())
@@ -794,6 +908,20 @@ public:
}
}
+ static LLUICachedControl<bool> show_sun_beacon("sunbeacon", false);
+ static LLUICachedControl<bool> show_moon_beacon("moonbeacon", false);
+
+ if (show_sun_beacon)
+ {
+ addText(xpos, ypos, beacon_sun);
+ ypos += y_inc;
+ }
+ if (show_moon_beacon)
+ {
+ addText(xpos, ypos, beacon_moon);
+ ypos += y_inc;
+ }
+
if(log_texture_traffic)
{
U32 old_y = ypos ;
@@ -861,6 +989,18 @@ public:
void draw()
{
LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT);
+
+ // Camera matrix text is hard to see again a white background
+ // Add a dark background underneath the matrices for readability (contrast)
+ if (mBackRectCamera1.mTop >= 0)
+ {
+ mBackColor.setAlpha( 0.75f );
+ gl_rect_2d(mBackRectCamera1, mBackColor, true);
+
+ mBackColor.setAlpha( 0.66f );
+ gl_rect_2d(mBackRectCamera2, mBackColor, true);
+ }
+
for (line_list_t::iterator iter = mLineList.begin();
iter != mLineList.end(); ++iter)
{
@@ -869,7 +1009,6 @@ public:
LLFontGL::LEFT, LLFontGL::TOP,
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
}
- mLineList.clear();
}
};
@@ -898,7 +1037,18 @@ LLViewerWindow::Params::Params()
{}
-BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask)
+{
+ if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized())
+ {
+ // If the current tool didn't process the click, we should show
+ // the pie menu. This can be done by passing the event to the pie
+ // menu tool.
+ LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
+ }
+}
+
+BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
{
const char* buttonname = "";
const char* buttonstatestr = "";
@@ -922,28 +1072,30 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
switch (clicktype)
{
- case LLMouseHandler::CLICK_LEFT:
+ case CLICK_LEFT:
mLeftMouseDown = down;
buttonname = "Left";
break;
- case LLMouseHandler::CLICK_RIGHT:
+ case CLICK_RIGHT:
mRightMouseDown = down;
buttonname = "Right";
break;
- case LLMouseHandler::CLICK_MIDDLE:
+ case CLICK_MIDDLE:
mMiddleMouseDown = down;
buttonname = "Middle";
break;
- case LLMouseHandler::CLICK_DOUBLELEFT:
+ case CLICK_DOUBLELEFT:
mLeftMouseDown = down;
buttonname = "Left Double Click";
break;
- case LLMouseHandler::CLICK_BUTTON4:
+ case CLICK_BUTTON4:
buttonname = "Button 4";
break;
- case LLMouseHandler::CLICK_BUTTON5:
+ case CLICK_BUTTON5:
buttonname = "Button 5";
break;
+ default:
+ break; // COUNT and NONE
}
LLView::sMouseHandlerMessage.clear();
@@ -994,6 +1146,11 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
}
+ else if (down && clicktype == CLICK_RIGHT)
+ {
+ handlePieMenu(x, y, mask);
+ r = TRUE;
+ }
return r;
}
@@ -1040,7 +1197,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
return TRUE;
}
-
+ if (down && clicktype == CLICK_RIGHT)
+ {
+ handlePieMenu(x, y, mask);
+ return TRUE;
+ }
+
// If we got this far on a down-click, it wasn't handled.
// Up-clicks, though, are always handled as far as the OS is concerned.
BOOL default_rtn = !down;
@@ -1059,7 +1221,8 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
mMouseDownTimer.reset();
}
BOOL down = TRUE;
- return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
+ //handleMouse() loops back to LLViewerWindow::handleAnyMouseClick
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
}
BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask)
@@ -1067,8 +1230,7 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
// try handling as a double-click first, then a single-click if that
// wasn't handled.
BOOL down = TRUE;
- if (handleAnyMouseClick(window, pos, mask,
- LLMouseHandler::CLICK_DOUBLELEFT, down))
+ if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down))
{
return TRUE;
}
@@ -1082,47 +1244,24 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
mMouseDownTimer.stop();
}
BOOL down = FALSE;
- return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
}
-
-
BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
- S32 x = pos.mX;
- S32 y = pos.mY;
- x = ll_round((F32)x / mDisplayScale.mV[VX]);
- y = ll_round((F32)y / mDisplayScale.mV[VY]);
-
BOOL down = TRUE;
- BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
- if (handle)
- return handle;
-
- // *HACK: this should be rolled into the composite tool logic, not
- // hardcoded at the top level.
- if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized())
- {
- // If the current tool didn't process the click, we should show
- // the pie menu. This can be done by passing the event to the pie
- // menu tool.
- LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
- // show_context_menu( x, y, mask );
- }
-
- return TRUE;
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
}
BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = FALSE;
- return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
+ return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
}
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = TRUE;
- LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true);
- handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+ gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
// Always handled as far as the OS is concerned.
return TRUE;
@@ -1277,8 +1416,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = FALSE;
- LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false);
- handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+ gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
// Always handled as far as the OS is concerned.
return TRUE;
@@ -1289,12 +1427,10 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask
switch (button)
{
case 4:
- LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down);
- handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down);
+ gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON4, down);
break;
case 5:
- LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down);
- handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down);
+ gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON5, down);
break;
default:
break;
@@ -1380,6 +1516,7 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
void LLViewerWindow::handleQuit(LLWindow *window)
{
+ LL_INFOS() << "Window forced quit" << LL_ENDL;
LLAppViewer::instance()->forceQuit();
}
@@ -1440,9 +1577,6 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
{
- // Let the voice chat code check for its PTT key. Note that this never affects event processing.
- LLVoiceClient::getInstance()->keyDown(key, mask);
-
if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
{
gAgent.clearAFK();
@@ -1461,14 +1595,12 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated)
return FALSE;
}
- return gViewerKeyboard.handleKey(key, mask, repeated);
+ // remaps, handles ignored cases and returns back to viewer window.
+ return gViewerInput.handleKey(key, mask, repeated);
}
BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
{
- // Let the voice chat code check for its PTT key. Note that this never affects event processing.
- LLVoiceClient::getInstance()->keyUp(key, mask);
-
// Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera
LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance();
if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp)
@@ -1476,13 +1608,13 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
tool_inspectp->keyUp(key, mask);
}
- return gViewerKeyboard.handleKeyUp(key, mask);
+ return gViewerInput.handleKeyUp(key, mask);
}
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
- gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
+ gViewerInput.scanKey(key, key_down, key_up, key_level);
return; // Be clear this function returns nothing
}
@@ -1587,6 +1719,11 @@ void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
handleScrollWheel( clicks );
}
+void LLViewerWindow::handleScrollHWheel(LLWindow *window, S32 clicks)
+{
+ handleScrollHWheel(clicks);
+}
+
void LLViewerWindow::handleWindowBlock(LLWindow *window)
{
send_agent_pause();
@@ -1779,8 +1916,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
ms_sleep(5000) ; //wait for 5 seconds.
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
-#if LL_LINUX || LL_SOLARIS
- LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt or README-solaris.txt for further information."
+#if LL_LINUX
+ LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly. See README-linux.txt for further information."
<< LL_ENDL;
#else
LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
@@ -1987,6 +2124,11 @@ void LLViewerWindow::initBase()
LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");
// Load the toolbar view from file
gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance());
+ if (!gToolBarView)
+ {
+ LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, "
+ << "if this problem happens again, please validate your installation." << LL_ENDL;
+ }
gToolBarView->setShape(panel_holder->getLocalRect());
// Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())
gToolBarView->setVisible(FALSE);
@@ -2290,7 +2432,6 @@ void LLViewerWindow::shutdownGL()
LLViewerWindow::~LLViewerWindow()
{
LL_INFOS() << "Destroying Window" << LL_ENDL;
- gDebugWindowProc = TRUE; // event catching, at this point it shouldn't output at all
destroyWindow();
delete mDebugText;
@@ -2381,6 +2522,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// round up when converting coordinates to make sure there are no gaps at edge of window
LLView::sForceReshape = display_scale_changed;
mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
+ if (display_scale_changed)
+ {
+ // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass()
+ LLPanelLogin::reshapePanel();
+ }
LLView::sForceReshape = FALSE;
// clear font width caches
@@ -2472,7 +2618,7 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
}
else
{
- switch (LLVersionInfo::getViewerMaturity())
+ switch (LLVersionInfo::instance().getViewerMaturity())
{
case LLVersionInfo::TEST_VIEWER:
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" );
@@ -2669,6 +2815,13 @@ void LLViewerWindow::draw()
// Takes a single keyup event, usually when UI is visible
BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
{
+ if (LLSetKeyBindDialog::recordKey(key, mask, FALSE))
+ {
+ LL_DEBUGS() << "KeyUp handled by LLSetKeyBindDialog" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+ return TRUE;
+ }
+
LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
if (keyboard_focus
@@ -2712,23 +2865,74 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// hide tooltips on keypress
LLToolTipMgr::instance().blockToolTips();
- LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+ // Menus get handled on key down instead of key up
+ // so keybindings have to be recorded before that
+ if (LLSetKeyBindDialog::recordKey(key, mask, TRUE))
+ {
+ LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+ LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+
if (keyboard_focus
- && !(mask & (MASK_CONTROL | MASK_ALT))
- && !gFocusMgr.getKeystrokesOnly())
- {
- // We have keyboard focus, and it's not an accelerator
- if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+ && !gFocusMgr.getKeystrokesOnly())
+ {
+#ifdef LL_WINDOWS
+ // On windows Alt Gr key generates additional Ctrl event, as result handling situations
+ // like 'AltGr + D' will result in 'Alt+Ctrl+D'. If it results in WM_CHAR, don't let it
+ // pass into menu or it will trigger 'develop' menu assigned to this combination on top
+ // of character handling.
+ // Alt Gr can be additionally modified by Shift
+ const MASK alt_gr = MASK_CONTROL | MASK_ALT;
+ if ((mask & alt_gr) != 0
+ && key >= 0x30
+ && key <= 0x5A
+ && (GetKeyState(VK_RMENU) & 0x8000) != 0
+ && (GetKeyState(VK_RCONTROL) & 0x8000) == 0) // ensure right control is not pressed, only left one
{
- return keyboard_focus->handleKey(key, mask, FALSE );
+ // Alt Gr key is represented as right alt and left control.
+ // Any alt+ctrl combination is treated as Alt Gr by TranslateMessage() and
+ // will generate a WM_CHAR message, but here we only treat virtual Alt Graph
+ // key by checking if this specific combination has unicode char.
+ //
+ // I decided to handle only virtual RAlt+LCtrl==AltGr combination to minimize
+ // impact on menu, but the right way might be to handle all Alt+Ctrl calls.
+
+ BYTE keyboard_state[256];
+ if (GetKeyboardState(keyboard_state))
+ {
+ const int char_count = 6;
+ wchar_t chars[char_count];
+ HKL layout = GetKeyboardLayout(0);
+ // ToUnicodeEx changes buffer state on OS below Win10, which is undesirable,
+ // but since we already did a TranslateMessage() in gatherInput(), this
+ // should have no negative effect
+ int res = ToUnicodeEx(key, 0, keyboard_state, chars, char_count, 1 << 2 /*do not modify buffer flag*/, layout);
+ if (res == 1 && chars[0] >= 0x20)
+ {
+ // Let it fall through to character handler and get a WM_CHAR.
+ return TRUE;
+ }
+ }
}
- else if (key < 0x80)
- {
- // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
- return (keyboard_focus != NULL);
- }
- }
+#endif
+
+ if (!(mask & (MASK_CONTROL | MASK_ALT)))
+ {
+ // We have keyboard focus, and it's not an accelerator
+ if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+ {
+ return keyboard_focus->handleKey(key, mask, FALSE);
+ }
+ else if (key < 0x80)
+ {
+ // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first.
+ return TRUE;
+ }
+ }
+ }
// let menus handle navigation keys for navigation
if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
@@ -2872,7 +3076,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// If "Pressing letter keys starts local chat" option is selected, we are not in mouselook,
// no view has keyboard focus, this is a printable character key (and no modifier key is
// pressed except shift), then give focus to nearby chat (STORM-560)
- if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
+ if ( LLStartUp::getStartupState() >= STATE_STARTED &&
+ gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
{
// Initialize nearby chat if it's missing
@@ -2926,7 +3131,8 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
{
if (mask != MASK_ALT)
{
- return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+ // remaps, handles ignored cases and returns back to viewer window.
+ return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
}
}
@@ -3002,6 +3208,49 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
return;
}
+void LLViewerWindow::handleScrollHWheel(S32 clicks)
+{
+ LLUI::getInstance()->resetMouseIdleTimer();
+
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ if (mouse_captor)
+ {
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y);
+ mouse_captor->handleScrollHWheel(local_x, local_y, clicks);
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel handled by captor " << mouse_captor->getName() << LL_ENDL;
+ }
+ return;
+ }
+
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ if (top_ctrl)
+ {
+ S32 local_x;
+ S32 local_y;
+ top_ctrl->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y);
+ if (top_ctrl->handleScrollHWheel(local_x, local_y, clicks)) return;
+ }
+
+ if (mRootView->handleScrollHWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks))
+ {
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel" << LLView::sMouseHandlerMessage << LL_ENDL;
+ }
+ return;
+ }
+ else if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel not handled by view" << LL_ENDL;
+ }
+
+ return;
+}
+
void LLViewerWindow::addPopup(LLView* popup)
{
if (mPopupView)
@@ -3807,7 +4056,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
F32 scale = vovolume->getLightRadius();
gGL.scalef(scale, scale, scale);
- LLColor4 color(vovolume->getLightColor(), .5f);
+ LLColor4 color(vovolume->getLightSRGBColor(), .5f);
gGL.color4fv(color.mV);
//F32 pixel_area = 100000.f;
@@ -3854,12 +4103,12 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
BOOL draw_handles = TRUE;
- if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected())
+ if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
{
draw_handles = FALSE;
}
- if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move)
+ if (tool == LLToolCompRotate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isMovableAvatarSelected())
{
draw_handles = FALSE;
}
@@ -4522,12 +4771,12 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
}
}
-BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format)
+BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, LLSnapshotModel::ESnapshotFormat format)
{
LL_INFOS() << "Saving snapshot to: " << filepath << LL_ENDL;
LLPointer<LLImageRaw> raw = new LLImageRaw;
- BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, FALSE, show_ui, do_rebuild);
+ BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, FALSE, show_ui, show_hud, do_rebuild);
if (success)
{
@@ -4586,26 +4835,22 @@ void LLViewerWindow::resetSnapshotLoc() const
gSavedPerAccountSettings.setString("SnapshotBaseDir", std::string());
}
-BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
+BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
{
- return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
+ return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, show_hud, do_rebuild, type);
}
// Saves the image from the screen to a raw image
// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
// the results over to the final raw image.
BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
- BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
+ BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
{
if (!raw)
{
return FALSE;
}
//check if there is enough memory for the snapshot image
- if(LLPipeline::sMemAllocationThrottled)
- {
- return FALSE ; //snapshot taking is disabled due to memory restriction.
- }
if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
{
if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3))
@@ -4629,7 +4874,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
- BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments;
+ BOOL hide_hud = !show_hud && LLPipeline::sShowHUDAttachments;
if (hide_hud)
{
LLPipeline::sShowHUDAttachments = FALSE;
@@ -4669,7 +4914,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) &&
(image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
{
- if (scratch_space.allocate(image_width, image_height, GL_DEPTH_COMPONENT, true, true))
+ 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();
@@ -4783,7 +5029,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
{
// Required for showing the GUI in snapshots and performing bloom composite overlay
// Call even if show_ui is FALSE
- LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
render_ui(scale_factor, subfield);
swap();
}
@@ -5049,6 +5294,14 @@ void LLViewerWindow::revealIntroPanel()
}
}
+void LLViewerWindow::initTextures(S32 location_id)
+{
+ if (mProgressView)
+ {
+ mProgressView->initTextures(location_id, LLGridManager::getInstance()->isInProductionGrid());
+ }
+}
+
void LLViewerWindow::setShowProgress(const BOOL show)
{
if (mProgressView)
@@ -5102,7 +5355,6 @@ void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string&
}
}
-
LLProgressView *LLViewerWindow::getProgressView() const
{
return mProgressView;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index d084642fdc..8a6df613dc 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -137,7 +137,7 @@ private:
};
-static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 6 * 1024; // max snapshot image size 6144 * 6144
+static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 * 7680 UHDTV2
class LLViewerWindow : public LLWindowCallbacks
{
@@ -175,8 +175,9 @@ public:
void initWorldUI();
void setUIVisibility(bool);
bool getUIVisibility();
+ void handlePieMenu(S32 x, S32 y, MASK mask);
- BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
+ BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
//
// LLWindowCallback interface implementation
@@ -208,6 +209,7 @@ public:
/*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item);
/*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
/*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks);
+ /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks);
/*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ void handleWindowBlock(LLWindow *window);
/*virtual*/ void handleWindowUnblock(LLWindow *window);
@@ -302,6 +304,7 @@ public:
BOOL getCursorHidden() { return mCursorHidden; }
void moveCursorToCenter(); // move to center of window
+ void initTextures(S32 location_id);
void setShowProgress(const BOOL show);
BOOL getShowProgress() const;
void setProgressString(const std::string& string);
@@ -326,6 +329,7 @@ public:
BOOL handleKey(KEY key, MASK mask);
BOOL handleKeyUp(KEY key, MASK mask);
void handleScrollWheel (S32 clicks);
+ void handleScrollHWheel (S32 clicks);
// add and remove views from "popup" layer
void addPopup(LLView* popup);
@@ -350,10 +354,10 @@ public:
// snapshot functionality.
// perhaps some of this should move to llfloatershapshot? -MG
- BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
+ BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, LLSnapshotModel::ESnapshotFormat format = LLSnapshotModel::SNAPSHOT_FORMAT_BMP);
BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
- BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
- BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
+ BOOL show_ui = TRUE, BOOL show_hud = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
+ 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;
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
index 97b405c1d0..acf25b9792 100644
--- a/indra/newview/llviewerwindowlistener.cpp
+++ b/indra/newview/llviewerwindowlistener.cpp
@@ -50,10 +50,11 @@ LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow):
// saveSnapshotArgs["width"] = LLSD::Integer();
// saveSnapshotArgs["height"] = LLSD::Integer();
// saveSnapshotArgs["showui"] = LLSD::Boolean();
+// saveSnapshotArgs["showhud"] = LLSD::Boolean();
// saveSnapshotArgs["rebuild"] = LLSD::Boolean();
// saveSnapshotArgs["type"] = LLSD::String();
add("saveSnapshot",
- "Save screenshot: [\"filename\"], [\"width\"], [\"height\"], [\"showui\"], [\"rebuild\"], [\"type\"]\n"
+ "Save screenshot: [\"filename\"], [\"width\"], [\"height\"], [\"showui\"], [\"showhud\"], [\"rebuild\"], [\"type\"]\n"
"type: \"COLOR\", \"DEPTH\"\n"
"Post on [\"reply\"] an event containing [\"ok\"]",
&LLViewerWindowListener::saveSnapshot,
@@ -83,6 +84,9 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
bool showui = true;
if (event.has("showui"))
showui = event["showui"].asBoolean();
+ bool showhud = true;
+ if (event.has("showhud"))
+ showhud = event["showhud"].asBoolean();
bool rebuild(event["rebuild"]); // defaults to false
LLSnapshotModel::ESnapshotLayerType type(LLSnapshotModel::SNAPSHOT_TYPE_COLOR);
if (event.has("type"))
@@ -96,7 +100,7 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
}
type = found->second;
}
- bool ok = mViewerWindow->saveSnapshot(event["filename"], width, height, showui, rebuild, type);
+ bool ok = mViewerWindow->saveSnapshot(event["filename"], width, height, showui, showhud, rebuild, type);
sendReply(LLSDMap("ok", ok), event);
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 3b51d07f96..f69b9b3861 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -38,6 +38,7 @@
#include "raytrace.h"
#include "llagent.h" // Get state values from here
+#include "llagentbenefits.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llanimationstates.h"
@@ -197,6 +198,8 @@ const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;
const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;
+const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60;
+
enum ERenderName
{
RENDER_NAME_NEVER,
@@ -204,6 +207,8 @@ enum ERenderName
RENDER_NAME_FADE
};
+#define JELLYDOLLS_SHOULD_IMPOSTOR
+
//-----------------------------------------------------------------------------
// Callback data
//-----------------------------------------------------------------------------
@@ -570,9 +575,9 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;
S32 LLVOAvatar::sFreezeCounter = 0;
-U32 LLVOAvatar::sMaxNonImpostors = 12; // overridden based on graphics setting
+U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
+bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
S32 LLVOAvatar::sNumVisibleAvatars = 0;
S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
@@ -599,7 +604,6 @@ BOOL LLVOAvatar::sShowFootPlane = FALSE;
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
-bool LLVOAvatar::sUseImpostors = false; // overwridden by RenderAvatarMaxNonImpostors
BOOL LLVOAvatar::sJointDebug = FALSE;
F32 LLVOAvatar::sUnbakedTime = 0.f;
F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
@@ -632,6 +636,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mMeshValid(FALSE),
mVisible(FALSE),
mLastImpostorUpdateFrameTime(0.f),
+ mLastImpostorUpdateReason(0),
mWindFreq(0.f),
mRipplePhase( 0.f ),
mBelowWater(FALSE),
@@ -654,6 +659,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNeedsSkin(FALSE),
mLastSkinTime(0.f),
mUpdatePeriod(1),
+ mOverallAppearance(AOA_INVISIBLE),
mVisualComplexityStale(true),
mVisuallyMuteSetting(AV_RENDER_NORMALLY),
mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
@@ -663,6 +669,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mFullyLoadedInitialized(FALSE),
mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
mLoadedCallbacksPaused(FALSE),
+ mLoadedCallbackTextures(0),
mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
mLastRezzedStatus(-1),
mIsEditingAppearance(FALSE),
@@ -697,6 +704,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
setAnimationData("Speed", &mSpeed);
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 0;
mNeedsAnimUpdate = TRUE;
mNeedsExtentUpdate = true;
@@ -752,8 +760,8 @@ std::string LLVOAvatar::avString() const
}
else
{
- std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
- return " Avatar '" + getFullname() + "' " + viz_string + " ";
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ return " Avatar '" + getFullname() + "' " + viz_string + " ";
}
}
@@ -883,8 +891,9 @@ BOOL LLVOAvatar::hasGray() const
S32 LLVOAvatar::getRezzedStatus() const
{
if (getIsCloud()) return 0;
- if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;
- if (isFullyTextured()) return 2;
+ bool textured = isFullyTextured();
+ if (textured && allBakedTexturesCompletelyDownloaded()) return 3;
+ if (textured) return 2;
llassert(hasGray());
return 1; // gray
}
@@ -1020,15 +1029,15 @@ void LLVOAvatar::dumpBakedStatus()
{
LL_CONT << " Unbaked (";
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
const ETextureIndex index = baked_dict->mTextureIndex;
if (!inst->isTextureDefined(index))
{
- LL_CONT << " " << (LLAvatarAppearanceDictionary::getInstance()->getTexture(index) ? LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName : "");
+ LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : "");
}
}
LL_CONT << " ) " << inst->getUnbakedPixelAreaRank();
@@ -1071,6 +1080,7 @@ void LLVOAvatar::resetImpostors()
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
avatar->mImpostor.release();
avatar->mNeedsImpostorUpdate = TRUE;
+ avatar->mLastImpostorUpdateReason = 1;
}
}
@@ -1114,6 +1124,7 @@ void LLVOAvatar::initClass()
LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints"));
LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged);
+
}
@@ -1314,72 +1325,84 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ if (isControlAvatar())
+ {
+ // Animated objects don't show system avatar but do need to include rigged meshes in their bounding box.
+ box_detail = 3;
+ }
+ else
+ {
+ // Jellydolled avatars ignore attachments, etc, use only system avatar.
+ box_detail = 1;
+ }
+ }
// FIXME the update_min_max function used below assumes there is a
// known starting point, but in general there isn't. Ideally the
// box update logic should be modified to handle the no-point-yet
// case. For most models, starting with the pelvis is safe though.
LLVector3 zero_pos;
- LLVector4a pos;
+ LLVector4a pos;
if (dist_vec(zero_pos, mPelvisp->getWorldPosition())<0.001)
{
// Don't use pelvis until av initialized
- pos.load3(getRenderPosition().mV);
+ pos.load3(getRenderPosition().mV);
}
else
{
pos.load3(mPelvisp->getWorldPosition().mV);
}
- newMin = pos;
- newMax = pos;
+ newMin = pos;
+ newMax = pos;
- //stretch bounding box by joint positions. Doing this for
- //control avs, where the polymeshes aren't maintained or
- //displayed, can give inaccurate boxes due to joints stuck at (0,0,0).
- if ((box_detail>=1) && !isControlAvatar())
+ if (box_detail>=1 && !isControlAvatar())
{
- for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
- {
- LLPolyMesh* mesh = i->second;
- for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++)
- {
- LLVector4a trans;
- trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
- update_min_max(newMin, newMax, trans);
- }
- }
-
+ //stretch bounding box by joint positions. Doing this for
+ //control avs, where the polymeshes aren't maintained or
+ //displayed, can give inaccurate boxes due to joints stuck at (0,0,0).
+ for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
+ {
+ LLPolyMesh* mesh = i->second;
+ for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++)
+ {
+ LLVector4a trans;
+ trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
+ update_min_max(newMin, newMax, trans);
+ }
+ }
}
- // Pad bounding box for starting joint, plus polymesh if
- // applicable. Subsequent calcs should be accurate enough to not
- // need padding.
- LLVector4a padding(0.25);
- newMin.sub(padding);
- newMax.add(padding);
+ // Pad bounding box for starting joint, plus polymesh if
+ // applicable. Subsequent calcs should be accurate enough to not
+ // need padding.
+ LLVector4a padding(0.25);
+ newMin.sub(padding);
+ newMax.add(padding);
- //stretch bounding box by static attachments
+ //stretch bounding box by static attachments
if (box_detail >= 2)
{
float max_attachment_span = get_default_max_prim_scale() * 5.0f;
-
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
+
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
- if (attachment->getValid())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
+ if (attachment->getValid())
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
// Don't we need to look at children of attached_object as well?
- const LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object && !attached_object->isHUDAttachment())
- {
+ const LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isHUDAttachment())
+ {
const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);
if (vol && vol->isAnimatedObject())
{
@@ -1401,39 +1424,39 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
continue;
}
- LLDrawable* drawable = attached_object->mDrawable;
- if (drawable && !drawable->isState(LLDrawable::RIGGED))
- {
- LLSpatialBridge* bridge = drawable->getSpatialBridge();
- if (bridge)
- {
- const LLVector4a* ext = bridge->getSpatialExtents();
- LLVector4a distance;
- distance.setSub(ext[1], ext[0]);
- LLVector4a max_span(max_attachment_span);
-
- S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
-
- // Only add the prim to spatial extents calculations if it isn't a megaprim.
- // max_attachment_span calculated at the start of the function
- // (currently 5 times our max prim size)
- if (lt == 0x7)
- {
- update_min_max(newMin,newMax,ext[0]);
- update_min_max(newMin,newMax,ext[1]);
- }
- }
- }
- }
- }
- }
- }
+ LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable && !drawable->isState(LLDrawable::RIGGED))
+ {
+ LLSpatialBridge* bridge = drawable->getSpatialBridge();
+ if (bridge)
+ {
+ const LLVector4a* ext = bridge->getSpatialExtents();
+ LLVector4a distance;
+ distance.setSub(ext[1], ext[0]);
+ LLVector4a max_span(max_attachment_span);
+
+ S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
+
+ // Only add the prim to spatial extents calculations if it isn't a megaprim.
+ // max_attachment_span calculated at the start of the function
+ // (currently 5 times our max prim size)
+ if (lt == 0x7)
+ {
+ update_min_max(newMin,newMax,ext[0]);
+ update_min_max(newMin,newMax,ext[1]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
// Stretch bounding box by rigged mesh joint boxes
if (box_detail>=3)
{
- updateRiggingInfo();
+ updateRiggingInfo();
for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
{
LLJoint *joint = getJoint(joint_num);
@@ -1573,13 +1596,16 @@ void LLVOAvatar::renderCollisionVolumes()
}
}
-void LLVOAvatar::renderBones()
+void LLVOAvatar::renderBones(const std::string &selected_joint)
{
LLGLEnable blend(GL_BLEND);
avatar_joint_list_t::iterator iter = mSkeleton.begin();
- avatar_joint_list_t::iterator end = mSkeleton.end();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+ // For selected joints
+ static LLVector3 SELECTED_COLOR_OCCLUDED(1.0f, 1.0f, 0.0f);
+ static LLVector3 SELECTED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
// For bones with position overrides defined
static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f);
static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
@@ -1606,7 +1632,18 @@ void LLVOAvatar::renderBones()
LLVector3 pos;
LLUUID mesh_id;
- if (jointp->hasAttachmentPosOverride(pos,mesh_id))
+ F32 sphere_scale = SPHERE_SCALEF;
+
+ // We are in render, so it is preferable to implement selection
+ // in a different way, but since this is for debug/preview, this
+ // is low priority
+ if (jointp->getName() == selected_joint)
+ {
+ sphere_scale *= 16;
+ occ_color = SELECTED_COLOR_OCCLUDED;
+ visible_color = SELECTED_COLOR_VISIBLE;
+ }
+ else if (jointp->hasAttachmentPosOverride(pos,mesh_id))
{
occ_color = OVERRIDE_COLOR_OCCLUDED;
visible_color = OVERRIDE_COLOR_VISIBLE;
@@ -1627,7 +1664,6 @@ void LLVOAvatar::renderBones()
LLVector3 begin_pos(0,0,0);
LLVector3 end_pos(jointp->getEnd());
- F32 sphere_scale = SPHERE_SCALEF;
gGL.pushMatrix();
gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
@@ -2006,6 +2042,38 @@ void LLVOAvatar::resetVisualParams()
}
}
+void LLVOAvatar::applyDefaultParams()
+{
+ // These are params from avs with newly created copies of shape,
+ // skin, hair, eyes, plus gender set as noted. Run arche_tool.py
+ // to get params from some other xml appearance dump.
+ std::map<S32, U8> male_params = {
+ {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+ };
+ std::map<S32, U8> female_params = {
+ {1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+ };
+ std::map<S32, U8> *params = NULL;
+ if (getSex() == SEX_MALE)
+ params = &male_params;
+ else
+ params = &female_params;
+
+ for( auto it = params->begin(); it != params->end(); ++it)
+ {
+ LLVisualParam* param = getVisualParam(it->first);
+ if( !param )
+ {
+ // invalid id
+ break;
+ }
+
+ U8 value = it->second;
+ F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+ param->setWeight(newWeight);
+ }
+}
+
//-----------------------------------------------------------------------------
// resetSkeleton()
//-----------------------------------------------------------------------------
@@ -2045,8 +2113,10 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
}
- // Reset attachment points (buildSkeleton only does bones and CVs)
- bool ignore_hud_joints = true;
+ // Reset attachment points
+ // BuildSkeleton only does bones and CVs but we still need to reinit huds
+ // since huds can be animated.
+ bool ignore_hud_joints = !isSelf();
initAttachmentPoints(ignore_hud_joints);
// Fix up collision volumes
@@ -2066,15 +2136,30 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
}
// Reset tweakable params to preserved state
- if (mLastProcessedAppearance)
- {
- bool slam_params = true;
- applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
- }
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ if (mLastProcessedAppearance)
+ {
+ bool slam_params = true;
+ applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+ }
+ }
+ else
+ {
+ // Stripped down approximation of
+ // applyParsedAppearanceMessage, but with alternative default
+ // (jellydoll) params
+ setCompositeUpdatesEnabled( FALSE );
+ gPipeline.markGLRebuild(this);
+ applyDefaultParams();
+ setCompositeUpdatesEnabled( TRUE );
+ updateMeshTextures();
+ updateMeshVisibility();
+ }
updateVisualParams();
// Restore attachment pos overrides
- updateAttachmentOverrides();
+ updateAttachmentOverrides();
// Animations
if (reset_animations)
@@ -2407,6 +2492,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
}
static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE("Avatar Update");
+static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE_COMPLEXITY("Avatar Update Complexity");
static LLTrace::BlockTimerStatHandle FTM_JOINT_UPDATE("Update Joints");
//------------------------------------------------------------------------
@@ -2449,14 +2535,13 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
return;
}
- if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))
+ if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())
{
return;
}
// Update should be happening max once per frame.
- const S32 upd_freq = 4; // force update every upd_freq frames.
if ((mLastAnimExtents[0]==LLVector3())||
(mLastAnimExtents[1])==LLVector3())
{
@@ -2464,6 +2549,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
}
else
{
+ const S32 upd_freq = 4; // force update every upd_freq frames.
mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
}
@@ -2548,8 +2634,41 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
}
idleUpdateNameTag( mLastRootPos );
+
+ // Complexity has stale mechanics, but updates still can be very rapid
+ // so spread avatar complexity calculations over frames to lesen load from
+ // rapid updates and to make sure all avatars are not calculated at once.
+ S32 compl_upd_freq = 20;
+ if (isControlAvatar())
+ {
+ // animeshes do not (or won't) have impostors nor change outfis,
+ // no need for high frequency
+ compl_upd_freq = 100;
+ }
+ else if (mLastRezzedStatus <= 0) //cloud or init
+ {
+ compl_upd_freq = 60;
+ }
+ else if (isSelf())
+ {
+ compl_upd_freq = 5;
+ }
+ else if (mLastRezzedStatus == 1) //'grey', not fully loaded
+ {
+ compl_upd_freq = 40;
+ }
+ else if (isInMuteList()) //cheap, buffers value from search
+ {
+ compl_upd_freq = 100;
+ }
+
+ if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY);
idleUpdateRenderComplexity();
}
+ idleUpdateDebugInfo();
+}
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
{
@@ -2675,7 +2794,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
BOOL visible = isVisible() || mNeedsAnimUpdate;
// update attachments positions
- if (detailed_update || !sUseImpostors)
+ if (detailed_update)
{
LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
@@ -2735,6 +2854,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
{
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 2;
}
}
@@ -2746,6 +2866,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (dist_diff/mImpostorDistance > 0.1f)
{
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 3;
}
else
{
@@ -2758,6 +2879,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (diff.getLength3().getF32() > 0.05f)
{
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 4;
}
else
{
@@ -2765,6 +2887,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (diff.getLength3().getF32() > 0.05f)
{
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 5;
}
}
}
@@ -2773,13 +2896,13 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (mDrawable.notNull())
{
- mDrawable->movePartition();
+ mDrawable->movePartition();
- //force a move if sitting on an active object
- if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
- {
- gPipeline.markMoved(mDrawable, TRUE);
- }
+ //force a move if sitting on an active object
+ if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
+ {
+ gPipeline.markMoved(mDrawable, TRUE);
+ }
}
}
@@ -2859,7 +2982,10 @@ F32 LLVOAvatar::calcMorphAmount()
void LLVOAvatar::idleUpdateLipSync(bool voice_enabled)
{
// Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
- if ( voice_enabled && (LLVoiceClient::getInstance()->lipSyncEnabled()) && LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
+ if ( voice_enabled
+ && mLastRezzedStatus > 0 // no point updating lip-sync for clouds
+ && (LLVoiceClient::getInstance()->lipSyncEnabled())
+ && LLVoiceClient::getInstance()->getIsSpeaking( mID ) )
{
F32 ooh_morph_amount = 0.0f;
F32 aah_morph_amount = 0.0f;
@@ -2953,7 +3079,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
void LLVOAvatar::idleUpdateWindEffect()
{
// update wind effect
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
{
F32 hover_strength = 0.f;
F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
@@ -3207,7 +3333,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
std::string title_str = title->getString();
LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerifSmall());
+ LLFontGL::getFontSansSerifSmall(), true);
}
static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true);
@@ -3227,7 +3353,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
if (show_display_names)
{
addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerif());
+ LLFontGL::getFontSansSerif(), true);
}
// Suppress SLID display if display name matches exactly (ugh)
if (show_usernames && !av_name.isDisplayNameDefault())
@@ -3235,14 +3361,14 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
// *HACK: Desaturate the color
LLColor4 username_color = name_tag_color * 0.83f;
addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
- LLFontGL::getFontSansSerifSmall());
+ LLFontGL::getFontSansSerifSmall(), true);
}
}
else
{
const LLFontGL* font = LLFontGL::getFontSansSerif();
std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
- addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
+ addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true);
}
mNameAway = is_away;
@@ -3334,7 +3460,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
}
}
-void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font)
+void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses)
{
llassert(mNameText);
if (mVisibleChat)
@@ -3343,7 +3469,7 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,
}
else
{
- mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
+ mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses);
}
mNameIsSet |= !line.empty();
}
@@ -3505,14 +3631,19 @@ bool LLVOAvatar::isVisuallyMuted()
muted = false;
}
else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
- { // Always want to see this AV as an impostor
+ {
+#ifdef JELLYDOLLS_SHOULD_IMPOSTOR
muted = true;
+ // Always want to see this AV as an impostor
+#else
+ muted = false;
+#endif
}
else if (isInMuteList())
{
muted = true;
}
- else
+ else
{
muted = isTooComplex();
}
@@ -3521,7 +3652,7 @@ bool LLVOAvatar::isVisuallyMuted()
return muted;
}
-bool LLVOAvatar::isInMuteList()
+bool LLVOAvatar::isInMuteList() const
{
bool muted = false;
F64 now = LLFrameTimer::getTotalSeconds();
@@ -3583,9 +3714,14 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
if (hover_offset[2] != 0.0)
{
debug_line += llformat(" hov_z: %.3f", hover_offset[2]);
- debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
+ debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
}
+ if (mInAir)
+ {
+ debug_line += " A";
+
+ }
LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
LLVector3 normal;
@@ -3598,9 +3734,38 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
LLVector3 pelvis_pos = mPelvisp->getPosition();
debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]);
- S32 is_visible = (S32) isVisible();
- S32 is_m_visible = (S32) mVisible;
- debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
+ const LLVector3& scale = getScale();
+ debug_line += llformat(" scale-z %.3f", scale[2]);
+ S32 is_visible = (S32) isVisible();
+ S32 is_m_visible = (S32) mVisible;
+ debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
+
+ AvatarOverallAppearance aoa = getOverallAppearance();
+ if (aoa == AOA_NORMAL)
+ {
+ debug_line += " N";
+ }
+ else if (aoa == AOA_JELLYDOLL)
+ {
+ debug_line += " J";
+ }
+ else
+ {
+ debug_line += " I";
+ }
+
+ if (mMeshValid)
+ {
+ debug_line += "m";
+ }
+ else
+ {
+ debug_line += "-";
+ }
+ if (isImpostor())
+ {
+ debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)));
+ }
addDebugText(debug_line);
}
@@ -3642,13 +3807,13 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU
void LLVOAvatar::updateAnimationDebugText()
{
- for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
- iter != mMotionController.getActiveMotions().end(); ++iter)
+ for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
+ iter != mMotionController.getActiveMotions().end(); ++iter)
+ {
+ LLMotion* motionp = *iter;
+ if (motionp->getMinPixelArea() < getPixelArea())
{
- LLMotion* motionp = *iter;
- if (motionp->getMinPixelArea() < getPixelArea())
- {
- std::string output;
+ std::string output;
std::string motion_name = motionp->getName();
if (motion_name.empty())
{
@@ -3665,73 +3830,74 @@ void LLVOAvatar::updateAnimationDebugText()
}
}
if (motion_name.empty())
+ {
+ std::string name;
+ if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
{
- std::string name;
- if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
+ name = motionp->getID().asString();
+ LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
+ for (; anim_it != mAnimationSources.end(); ++anim_it)
{
- name = motionp->getID().asString();
- LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
- for (; anim_it != mAnimationSources.end(); ++anim_it)
+ if (anim_it->second == motionp->getID())
{
- if (anim_it->second == motionp->getID())
+ LLViewerObject* object = gObjectList.findObject(anim_it->first);
+ if (!object)
+ {
+ break;
+ }
+ if (object->isAvatar())
{
- LLViewerObject* object = gObjectList.findObject(anim_it->first);
- if (!object)
+ if (mMotionController.mIsSelf)
{
- break;
+ // Searching inventory by asset id is really long
+ // so just mark as inventory
+ // Also item is likely to be named by LLPreviewAnim
+ name += "(inventory)";
}
- if (object->isAvatar())
+ }
+ else
+ {
+ LLViewerInventoryItem* item = NULL;
+ if (!object->isInventoryDirty())
{
- if (mMotionController.mIsSelf)
- {
- // Searching inventory by asset id is really long
- // so just mark as inventory
- // Also item is likely to be named by LLPreviewAnim
- name += "(inventory)";
- }
+ item = object->getInventoryItemByAsset(motionp->getID());
+ }
+ if (item)
+ {
+ name = item->getName();
+ }
+ else if (object->isAttachment())
+ {
+ name += "(att:" + getAttachmentItemName() + ")";
}
else
{
- LLViewerInventoryItem* item = NULL;
- if (!object->isInventoryDirty())
- {
- item = object->getInventoryItemByAsset(motionp->getID());
- }
- if (item)
- {
- name = item->getName();
- }
- else if (object->isAttachment())
- {
- name += "(" + getAttachmentItemName() + ")";
- }
- else
- {
- // in-world object, name or content unknown
- name += "(in-world)";
- }
+ // in-world object, name or content unknown
+ name += "(in-world)";
}
- break;
}
+ break;
}
}
- else
- {
- name = LLUUID::null.asString();
- }
- output = llformat("%s - %d",
- name.c_str(),
- (U32)motionp->getPriority());
}
else
{
- output = llformat("%s - %d",
- motion_name.c_str(),
- (U32)motionp->getPriority());
+ name = LLUUID::null.asString();
}
- addDebugText(output);
+ motion_name = name;
+ }
+ std::string motion_tag = "";
+ if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end())
+ {
+ motion_tag = "*";
}
+ output = llformat("%s%s - %d",
+ motion_name.c_str(),
+ motion_tag.c_str(),
+ (U32)motionp->getPriority());
+ addDebugText(output);
}
+ }
}
void LLVOAvatar::updateDebugText()
@@ -3860,7 +4026,14 @@ void LLVOAvatar::updateFootstepSounds()
// computeUpdatePeriod()
// Factored out from updateCharacter()
// Set new value for mUpdatePeriod based on distance and various other factors.
-//------------------------------------------------------------------------
+//
+// Note 10-2020: it turns out that none of these update period
+// calculations have been having any effect, because
+// mNeedsImpostorUpdate was not being set in updateCharacter(). So
+// it's really open to question whether we want to enable time based updates, and if
+// so, at what rate. Leaving the rates as given would lead to
+// drastically more frequent impostor updates than we've been doing all these years.
+// ------------------------------------------------------------------------
void LLVOAvatar::computeUpdatePeriod()
{
bool visually_muted = isVisuallyMuted();
@@ -3868,7 +4041,7 @@ void LLVOAvatar::computeUpdatePeriod()
&& isVisible()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
- && sUseImpostors
+ && (sLimitNonImpostors || visually_muted)
&& !mNeedsAnimUpdate
&& !sFreezeCounter)
{
@@ -3876,11 +4049,14 @@ void LLVOAvatar::computeUpdatePeriod()
LLVector4a size;
size.setSub(ext[1],ext[0]);
F32 mag = size.getLength3().getF32()*0.5f;
+
+ const S32 UPDATE_RATE_SLOW = 64;
+ const S32 UPDATE_RATE_MED = 48;
+ const S32 UPDATE_RATE_FAST = 32;
- F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
if (visually_muted)
- { // visually muted avatars update at 16 hz
- mUpdatePeriod = 16;
+ { // visually muted avatars update at lowest rate
+ mUpdatePeriod = UPDATE_RATE_SLOW;
}
else if (! shouldImpostor()
|| mDrawable->mDistanceWRTCamera < 1.f + mag)
@@ -3889,29 +4065,29 @@ void LLVOAvatar::computeUpdatePeriod()
// impostor camera near clip plane
mUpdatePeriod = 1;
}
- else if ( shouldImpostor(4) )
+ else if ( shouldImpostor(4.0) )
{ //background avatars are REALLY slow updating impostors
- mUpdatePeriod = 16;
+ mUpdatePeriod = UPDATE_RATE_SLOW;
}
- else if ( shouldImpostor(3) )
- { //back 25% of max visible avatars are slow updating impostors
- mUpdatePeriod = 8;
+ else if (mLastRezzedStatus <= 0)
+ {
+ // Don't update cloud avatars too often
+ mUpdatePeriod = UPDATE_RATE_SLOW;
}
- else if (mImpostorPixelArea <= impostor_area)
- { // stuff in between gets an update period based on pixel area
- mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8);
+ else if ( shouldImpostor(3.0) )
+ { //back 25% of max visible avatars are slow updating impostors
+ mUpdatePeriod = UPDATE_RATE_MED;
}
- else
+ else
{
//nearby avatars, update the impostors more frequently.
- mUpdatePeriod = 4;
+ mUpdatePeriod = UPDATE_RATE_FAST;
}
}
else
{
mUpdatePeriod = 1;
}
-
}
//------------------------------------------------------------------------
@@ -4182,7 +4358,33 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
if (!isSitting() && !was_sit_ground_constrained)
{
root_pos += LLVector3d(getHoverOffset());
- }
+ if (getOverallAppearance() == AOA_JELLYDOLL)
+ {
+ F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]);
+ root_pos[2] += offz;
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " root adjust offz " << offz
+ // << " scalez " << getScale()[VZ]
+ // << " bsz " << mBodySize.mV[VZ]
+ // << LL_ENDL;
+ // }
+ }
+ }
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " scalez " << getScale()[VZ]
+ // << " bsz " << mBodySize.mV[VZ]
+ // << " root pos " << root_pos[2]
+ // << " curr rootz " << mRoot->getPosition()[2]
+ // << " pp-z " << mPelvisp->getPosition()[2]
+ // << " renderpos " << getRenderPosition()
+ // << LL_ENDL;
+ // }
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
if (cav)
@@ -4193,6 +4395,14 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
else
{
LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
+ // if (!isSelf() && !isControlAvatar())
+ // {
+ // LL_DEBUGS("Avatar") << "av " << getFullname()
+ // << " frame " << LLFrameTimer::getFrameCount()
+ // << " newPosition " << newPosition
+ // << " renderpos " << getRenderPosition()
+ // << LL_ENDL;
+ // }
if (newPosition != mRoot->getXform()->getWorldPosition())
{
mRoot->touch();
@@ -4223,6 +4433,37 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
}
//------------------------------------------------------------------------
+// LLVOAvatar::computeNeedsUpdate()
+//
+// Most of the logic here is to figure out when to periodically update impostors.
+// Non-impostors have mUpdatePeriod == 1 and will need update every frame.
+//------------------------------------------------------------------------
+bool LLVOAvatar::computeNeedsUpdate()
+{
+ const F32 MAX_IMPOSTOR_INTERVAL = 4.0f;
+ computeUpdatePeriod();
+
+ bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0);
+
+ bool needs_update_by_max_time = ((gFrameTimeSeconds-mLastImpostorUpdateFrameTime)> MAX_IMPOSTOR_INTERVAL);
+ bool needs_update = needs_update_by_frame_count || needs_update_by_max_time;
+
+ if (needs_update && !isSelf())
+ {
+ if (needs_update_by_max_time)
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 11;
+ }
+ else
+ {
+ //mNeedsImpostorUpdate = TRUE;
+ //mLastImpostorUpdateReason = 10;
+ }
+ }
+ return needs_update;
+}
+
// updateCharacter()
//
// This is called for all avatars, so there are 4 possible situations:
@@ -4245,7 +4486,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
// simulator.
//
//------------------------------------------------------------------------
-BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
+bool LLVOAvatar::updateCharacter(LLAgent &agent)
{
updateDebugText();
@@ -4257,6 +4498,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
BOOL visible = isVisible();
bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing
bool is_attachment = false;
+
if (is_control_avatar)
{
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
@@ -4276,24 +4518,30 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
//--------------------------------------------------------------------
// The rest should only be done occasionally for far away avatars.
- // Set mUpdatePeriod and visible based on distance and other criteria.
+ // Set mUpdatePeriod and visible based on distance and other criteria,
+ // and flag for impostor update if needed.
//--------------------------------------------------------------------
- computeUpdatePeriod();
- visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
-
+ bool needs_update = computeNeedsUpdate();
+
//--------------------------------------------------------------------
- // Early out if not visible and not self
+ // Early out if does not need update and not self
// don't early out for your own avatar, as we rely on your animations playing reliably
// for example, the "turn around" animation when entering customize avatar needs to trigger
// even when your avatar is offscreen
//--------------------------------------------------------------------
- if (!visible && !isSelf())
+ if (!needs_update && !isSelf())
{
updateMotions(LLCharacter::HIDDEN_UPDATE);
return FALSE;
}
//--------------------------------------------------------------------
+ // Handle transitions between regular rendering, jellydoll, or invisible.
+ // Can trigger skeleton reset or animation changes
+ //--------------------------------------------------------------------
+ updateOverallAppearance();
+
+ //--------------------------------------------------------------------
// change animation time quanta based on avatar render load
//--------------------------------------------------------------------
// SL-763 the time step quantization does not currently work.
@@ -4336,12 +4584,17 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
mSpeed = speed;
// update animations
- if (mSpecialRenderMode == 1) // Animation Preview
+ if (!visible)
+ {
+ updateMotions(LLCharacter::HIDDEN_UPDATE);
+ }
+ else if (mSpecialRenderMode == 1) // Animation Preview
{
updateMotions(LLCharacter::FORCE_UPDATE);
}
else
{
+ // Might be better to do HIDDEN_UPDATE if cloud
updateMotions(LLCharacter::NORMAL_UPDATE);
}
@@ -4369,10 +4622,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// Update child joints as needed.
mRoot->updateWorldMatrixChildren();
- // System avatar mesh vertices need to be reskinned.
- mNeedsSkin = TRUE;
+ if (visible)
+ {
+ // System avatar mesh vertices need to be reskinned.
+ mNeedsSkin = TRUE;
+ }
- return TRUE;
+ return visible;
}
//-----------------------------------------------------------------------------
@@ -4655,7 +4911,7 @@ U32 LLVOAvatar::renderSkinned()
}
}
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
{
if (mNeedsSkin)
{
@@ -4804,19 +5060,29 @@ U32 LLVOAvatar::renderSkinned()
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
+ if (isUIAvatar() && mIsDummy)
+ {
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+ if (hair_mesh)
+ {
+ num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
+ first_pass = FALSE;
+ }
if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
- if (isTextureVisible(TEX_HEAD_BAKED) || isUIAvatar())
+
+ if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
{
LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
if (head_mesh)
{
- num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
}
first_pass = FALSE;
}
}
- if (isTextureVisible(TEX_UPPER_BAKED) || isUIAvatar())
+ if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
{
LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
if (upper_mesh)
@@ -4826,7 +5092,7 @@ U32 LLVOAvatar::renderSkinned()
first_pass = FALSE;
}
- if (isTextureVisible(TEX_LOWER_BAKED) || isUIAvatar())
+ if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
{
LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
if (lower_mesh)
@@ -4883,7 +5149,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
}
first_pass = FALSE;
}
- if (isTextureVisible(TEX_HAIR_BAKED))
+ if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL))
{
LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
if (hair_mesh)
@@ -4931,7 +5197,7 @@ U32 LLVOAvatar::renderRigid()
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
}
- if (isTextureVisible(TEX_EYES_BAKED) || isUIAvatar())
+ if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
{
LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
@@ -5109,7 +5375,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
{
for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
LLViewerFetchedTexture *imagep = NULL;
@@ -5118,7 +5384,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
if (texture_dict && texture_dict->mIsLocalTexture)
{
ids.insert(imagep->getID());
@@ -5252,7 +5518,7 @@ void LLVOAvatar::updateTextures()
mHasGrey = FALSE; // debug
for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
const LLTextureEntry *te = getTE(texture_index);
@@ -5275,7 +5541,7 @@ void LLVOAvatar::updateTextures()
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES;
if (texture_dict && texture_dict->mIsLocalTexture)
{
@@ -5318,12 +5584,28 @@ void LLVOAvatar::checkTextureLoading()
}
if(mLoadedCallbacksPaused == pause)
{
+ if (!pause && mFirstFullyVisible && mLoadedCallbackTextures < mCallbackTextureList.size())
+ {
+ // We still need to update 'loaded' textures count to decide on 'cloud' visibility
+ // Alternatively this can be done on TextureLoaded callbacks, but is harder to properly track
+ mLoadedCallbackTextures = 0;
+ for (LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
+ iter != mCallbackTextureList.end(); ++iter)
+ {
+ LLViewerFetchedTexture* tex = gTextureList.findImage(*iter);
+ if (tex && (tex->getDiscardLevel() >= 0 || tex->isMissingAsset()))
+ {
+ mLoadedCallbackTextures++;
+ }
+ }
+ }
return ;
}
if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty.
{
mLoadedCallbacksPaused = pause ;
+ mLoadedCallbackTextures = 0;
return ; //nothing to check.
}
@@ -5331,7 +5613,9 @@ void LLVOAvatar::checkTextureLoading()
{
return ; //have not been invisible for enough time.
}
-
+
+ mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0;
+
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
iter != mCallbackTextureList.end(); ++iter)
{
@@ -5352,9 +5636,15 @@ void LLVOAvatar::checkTextureLoading()
tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
tex->addTextureStats(START_AREA); //jump start the fetching again
+
+ // technically shouldn't need to account for missing, but callback might not have happened yet
+ if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset())
+ {
+ mLoadedCallbackTextures++; // consider it loaded (we have at least some data)
+ }
}
- }
- }
+ }
+ }
if(!pause)
{
@@ -5426,7 +5716,7 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
return url;
}
- const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
if (texture_entry != NULL)
{
url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
@@ -5536,8 +5826,8 @@ void LLVOAvatar::processAnimationStateChanges()
stopMotion(ANIM_AGENT_TARGET);
if (mEnableDefaultMotions)
{
- startMotion(ANIM_AGENT_BODY_NOISE);
- }
+ startMotion(ANIM_AGENT_BODY_NOISE);
+ }
}
// clear all current animations
@@ -5557,23 +5847,32 @@ void LLVOAvatar::processAnimationStateChanges()
++anim_it;
}
+ // if jellydolled, shelve all playing animations
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ mPlayingAnimations.clear();
+ }
+
// start up all new anims
- for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
+ if (getOverallAppearance() == AOA_NORMAL)
{
- AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
-
- // signaled but not playing, or different sequence id, start motion
- if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
+ for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
{
- if (processSingleAnimationStateChange(anim_it->first, TRUE))
+ AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
+
+ // signaled but not playing, or different sequence id, start motion
+ if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
{
- mPlayingAnimations[anim_it->first] = anim_it->second;
- ++anim_it;
- continue;
+ if (processSingleAnimationStateChange(anim_it->first, TRUE))
+ {
+ mPlayingAnimations[anim_it->first] = anim_it->second;
+ ++anim_it;
+ continue;
+ }
}
- }
- ++anim_it;
+ ++anim_it;
+ }
}
// clear source information for animations which have been stopped
@@ -6136,6 +6435,11 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
}
LLScopedContextString str("addAttachmentOverridesForObject " + getFullname());
+
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ return;
+ }
LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;
dumpStack("AnimatedObjectsStack");
@@ -6576,7 +6880,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints))
{
- //don't process hud joint for other avatars, or when doing a skeleton reset.
+ //don't process hud joint for other avatars.
continue;
}
@@ -6794,13 +7098,13 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
pipeline->allocDrawable(this);
mDrawable->setLit(FALSE);
- LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR);
+ LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*)gPipeline.getPool(mIsControlAvatar ? LLDrawPool::POOL_CONTROL_AV : LLDrawPool::POOL_AVATAR);
// Only a single face (one per avatar)
//this face will be splitted into several if its vertex buffer is too long.
mDrawable->setState(LLDrawable::ACTIVE);
mDrawable->addFace(poolp, NULL);
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
+ mDrawable->setRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR);
mNumInitFaces = mDrawable->getNumFaces() ;
@@ -6825,7 +7129,7 @@ static LLTrace::BlockTimerStatHandle FTM_UPDATE_AVATAR("Update Avatar");
BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
{
LL_RECORD_BLOCK_TIME(FTM_UPDATE_AVATAR);
- if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
+ if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)))
{
return TRUE;
}
@@ -7061,20 +7365,7 @@ U32 LLVOAvatar::getNumAttachments() const
//-----------------------------------------------------------------------------
S32 LLVOAvatar::getMaxAttachments() const
{
- const S32 MAX_AGENT_ATTACHMENTS = 38;
-
- S32 max_attach = MAX_AGENT_ATTACHMENTS;
-
- if (gAgent.getRegion())
- {
- LLSD features;
- gAgent.getRegion()->getSimulatorFeatures(features);
- if (features.has("MaxAgentAttachments"))
- {
- max_attach = features["MaxAgentAttachments"].asInteger();
- }
- }
- return max_attach;
+ return LLAgentBenefitsMgr::current().getAttachmentLimit();
}
//-----------------------------------------------------------------------------
@@ -7108,24 +7399,7 @@ U32 LLVOAvatar::getNumAnimatedObjectAttachments() const
//-----------------------------------------------------------------------------
S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const
{
- S32 max_attach = 0;
- if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits"))
- {
- max_attach = getMaxAttachments();
- }
- else
- {
- if (gAgent.getRegion())
- {
- LLSD features;
- gAgent.getRegion()->getSimulatorFeatures(features);
- if (features.has("AnimatedObjects"))
- {
- max_attach = features["AnimatedObjects"]["MaxAgentAnimatedObjectAttachments"].asInteger();
- }
- }
- }
- return max_attach;
+ return LLAgentBenefitsMgr::current().getAnimatedObjectLimit();
}
//-----------------------------------------------------------------------------
@@ -7363,7 +7637,8 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
mRoot->updateWorldMatrixChildren();
stopMotion(ANIM_AGENT_BODY_NOISE);
-
+
+ gAgentCamera.setInitSitRot(gAgent.getFrameAgent().getQuaternion());
}
//-----------------------------------------------------------------------------
@@ -7490,8 +7765,8 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
break; // Do nothing
}
- for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++tex_iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
@@ -7504,7 +7779,7 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
if (texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
+ return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex);
}
return FALSE;
}
@@ -7584,9 +7859,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)
}
// virtual
+// Do rigged mesh attachments display with this av?
bool LLVOAvatar::shouldRenderRigged() const
{
- return true;
+ if (getOverallAppearance() == AOA_NORMAL)
+ {
+ return true;
+ }
+ // TBD - render for AOA_JELLYDOLL?
+ return false;
}
// FIXME: We have an mVisible member, set in updateVisibility(), but this
@@ -7618,14 +7899,13 @@ bool LLVOAvatar::getIsCloud() const
);
}
-void LLVOAvatar::updateRezzedStatusTimers()
+void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status)
{
// State machine for rezzed status. Statuses are -1 on startup, 0
// = cloud, 1 = gray, 2 = downloading, 3 = full.
// Purpose is to collect time data for each it takes avatar to reach
// various loading landmarks: gray, textured (partial), textured fully.
- S32 rez_status = getRezzedStatus();
if (rez_status != mLastRezzedStatus)
{
LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
@@ -7795,8 +8075,21 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
// returns true if the value has changed.
BOOL LLVOAvatar::updateIsFullyLoaded()
{
- const bool loading = getIsCloud();
- updateRezzedStatusTimers();
+ S32 rez_status = getRezzedStatus();
+ bool loading = getIsCloud();
+ if (mFirstFullyVisible && !mIsControlAvatar)
+ {
+ loading = ((rez_status < 2)
+ // Wait at least 60s for unfinished textures to finish on first load,
+ // don't wait forever, it might fail. Even if it will eventually load by
+ // itself and update mLoadedCallbackTextures (or fail and clean the list),
+ // avatars are more time-sensitive than textures and can't wait that long.
+ || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
+ || !mPendingAttachment.empty()
+ || (rez_status < 3 && !isFullyBaked())
+ );
+ }
+ updateRezzedStatusTimers(rez_status);
updateRuthTimer(loading);
return processFullyLoadedChange(loading);
}
@@ -7832,13 +8125,22 @@ void LLVOAvatar::updateRuthTimer(bool loading)
BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
{
- // we wait a little bit before giving the all clear,
- // to let textures settle down
- const F32 PAUSE = 1.f;
+ // We wait a little bit before giving the 'all clear', to let things to
+ // settle down (models to snap into place, textures to get first packets)
+ const F32 LOADED_DELAY = 1.f;
+ const F32 FIRST_USE_DELAY = 3.f;
+
if (loading)
mFullyLoadedTimer.reset();
-
- mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
+
+ if (mFirstFullyVisible)
+ {
+ mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > FIRST_USE_DELAY);
+ }
+ else
+ {
+ mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY);
+ }
if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
{
@@ -7846,12 +8148,14 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
}
// did our loading state "change" from last call?
- // runway - why are we updating every 30 calls even if nothing has changed?
+ // FIXME runway - why are we updating every 30 calls even if nothing has changed?
+ // This causes updateLOD() to run every 30 frames, among other things.
const S32 UPDATE_RATE = 30;
BOOL changed =
((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call
(!mFullyLoadedInitialized) || // if we've never been called before
(mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change
+ BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded);
mPreviousFullyLoaded = mFullyLoaded;
mFullyLoadedInitialized = TRUE;
@@ -7862,7 +8166,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
// to know about outfit switching
LLAvatarRenderNotifier::getInstance()->updateNotificationState();
}
-
+
+ if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor())
+ {
+ // Fix for jellydoll initially invisible
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 6;
+ }
return changed;
}
@@ -7934,47 +8244,25 @@ void LLVOAvatar::updateMeshVisibility()
bool bake_flag[BAKED_NUM_INDICES];
memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool));
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
+ if (getOverallAppearance() == AOA_NORMAL)
{
- LLViewerJointAttachment* attachment = iter->second;
- if (attachment)
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment)
{
- LLViewerObject *objectp = attachment_iter->get();
- if (objectp)
- {
- for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
- {
- LLTextureEntry* tex_entry = objectp->getTE(face_index);
- bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
- bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
- bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
- bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
- bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
- bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
- bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
- bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
- bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
- bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
- bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
- }
- }
-
- LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
- iter1 != child_list.end(); ++iter1)
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- LLViewerObject* objectchild = *iter1;
- if (objectchild)
+ LLViewerObject *objectp = attachment_iter->get();
+ if (objectp)
{
- for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
+ for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
{
- LLTextureEntry* tex_entry = objectchild->getTE(face_index);
+ LLTextureEntry* tex_entry = objectp->getTE(face_index);
bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
@@ -7988,6 +8276,31 @@ void LLVOAvatar::updateMeshVisibility()
bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
}
}
+
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+ iter1 != child_list.end(); ++iter1)
+ {
+ LLViewerObject* objectchild = *iter1;
+ if (objectchild)
+ {
+ for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
+ {
+ LLTextureEntry* tex_entry = objectchild->getTE(face_index);
+ bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
+ bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
+ bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
+ bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
+ bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
+ bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
+ bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
+ bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
+ bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
+ bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
+ bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
+ }
+ }
+ }
}
}
}
@@ -8128,6 +8441,7 @@ void LLVOAvatar::updateMeshTextures()
LLViewerTexLayerSet* layerset = getTexLayerSet(i);
if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
{
+ // use last known good layer (no new one)
LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
mBakedTextureDatas[i].mIsUsed = TRUE;
@@ -8146,6 +8460,7 @@ void LLVOAvatar::updateMeshTextures()
}
else if (!isUsingLocalAppearance() && is_layer_baked[i])
{
+ // use new layer
LLViewerFetchedTexture* baked_img =
LLViewerTextureManager::staticCastToFetchedTexture(
getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
@@ -8165,10 +8480,15 @@ void LLVOAvatar::updateMeshTextures()
((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
- src_callback_list, paused);
+ src_callback_list, paused);
}
baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),
src_callback_list, paused );
+ if (baked_img->getDiscardLevel() < 0 && !paused)
+ {
+ // mLoadedCallbackTextures will be updated by checkTextureLoading() below
+ mLastTexCallbackAddedTime.reset();
+ }
// this could add paused texture callbacks
mLoadedCallbacksPaused |= paused;
@@ -8222,8 +8542,8 @@ void LLVOAvatar::updateMeshTextures()
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -8401,7 +8721,7 @@ void LLVOAvatar::releaseComponentTextures()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
if (!isTextureDefined(bakedDicEntry->mTextureIndex)
&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
@@ -8420,8 +8740,8 @@ void LLVOAvatar::releaseComponentTextures()
void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
{
LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -8562,13 +8882,16 @@ void LLVOAvatar::onFirstTEMessageReceived()
LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;
image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
src_callback_list, paused );
-
+ if (image->getDiscardLevel() < 0 && !paused)
+ {
+ mLastTexCallbackAddedTime.reset();
+ }
// this could add paused texture callbacks
mLoadedCallbacksPaused |= paused;
}
}
- mMeshTexturesDirty = TRUE;
+ mMeshTexturesDirty = TRUE;
gPipeline.markGLRebuild(this);
}
}
@@ -8908,7 +9231,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
mLastProcessedAppearance = contents;
bool slam_params = false;
- applyParsedAppearanceMessage(*contents, slam_params);
+ applyParsedAppearanceMessage(*contents, slam_params);
+ if (getOverallAppearance() != AOA_NORMAL)
+ {
+ resetSkeleton(false);
+ }
}
void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params)
@@ -9167,8 +9494,8 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
maskData->mLastDiscardLevel = discard_level; */
BOOL found_texture_id = false;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
@@ -9215,8 +9542,6 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
// static
void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
-
-
LLUUID *avatar_idp = (LLUUID *)userdata;
LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
@@ -9301,7 +9626,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
}
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
@@ -9436,7 +9761,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type)
{
// MULTIPLE_WEARABLES: extend to multiple wearables?
LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
@@ -9803,7 +10128,7 @@ BOOL LLVOAvatar::updateLOD()
return FALSE;
}
- if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
+ if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
{
return TRUE;
}
@@ -9981,7 +10306,7 @@ void LLVOAvatar::onActiveOverrideMeshesChanged()
U32 LLVOAvatar::getPartitionType() const
{
// Avatars merely exist as drawables in the bridge partition
- return LLViewerRegion::PARTITION_BRIDGE;
+ return mIsControlAvatar ? LLViewerRegion::PARTITION_CONTROL_AV : LLViewerRegion::PARTITION_AVATAR;
}
//static
@@ -9994,10 +10319,10 @@ void LLVOAvatar::updateImpostors()
iter != instances_copy.end(); ++iter)
{
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
- if (!avatar->isDead() && avatar->isVisible()
- && (
- (avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate())
- )
+ if (!avatar->isDead()
+ && avatar->isVisible()
+ && avatar->isImpostor()
+ && avatar->needsImpostorUpdate())
{
avatar->calcMutedAVColor();
gPipeline.generateImpostor(avatar);
@@ -10010,12 +10335,20 @@ void LLVOAvatar::updateImpostors()
// virtual
BOOL LLVOAvatar::isImpostor()
{
- return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
+ return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
}
-BOOL LLVOAvatar::shouldImpostor(const U32 rank_factor) const
+BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
{
- return (!isSelf() && sUseImpostors && mVisibilityRank > (sMaxNonImpostors * rank_factor));
+ if (isSelf())
+ {
+ return false;
+ }
+ if (isVisuallyMuted())
+ {
+ return true;
+ }
+ return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
}
BOOL LLVOAvatar::needsImpostorUpdate() const
@@ -10058,16 +10391,16 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
}
// static
-const U32 LLVOAvatar::IMPOSTORS_OFF = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
+const U32 LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
* slider in panel_preferences_graphics1.xml */
// static
void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
{
U32 oldmax = sMaxNonImpostors;
- bool oldflg = sUseImpostors;
+ bool oldflg = sLimitNonImpostors;
- if (IMPOSTORS_OFF <= newMaxNonImpostorsValue)
+ if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue)
{
sMaxNonImpostors = 0;
}
@@ -10075,13 +10408,13 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
{
sMaxNonImpostors = newMaxNonImpostorsValue;
}
- // the sUseImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
- sUseImpostors = (0 != sMaxNonImpostors);
- if ( oldflg != sUseImpostors )
+ // the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
+ sLimitNonImpostors = (0 != sMaxNonImpostors);
+ if ( oldflg != sLimitNonImpostors )
{
LL_DEBUGS("AvatarRender")
<< "was " << (oldflg ? "use" : "don't use" ) << " impostors (max " << oldmax << "); "
- << "now " << (sUseImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); "
+ << "now " << (sLimitNonImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); "
<< LL_ENDL;
}
}
@@ -10102,7 +10435,10 @@ void LLVOAvatar::idleUpdateRenderComplexity()
// Render Complexity
calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed
+}
+void LLVOAvatar::idleUpdateDebugInfo()
+{
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO))
{
std::string info_line;
@@ -10335,7 +10671,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Diagnostic list of all textures on our avatar
static std::set<LLUUID> all_textures;
- if (mVisualComplexityStale)
+ if (mVisualComplexityStale)
{
U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
LLVOVolume::texture_cost_t textures;
@@ -10344,7 +10680,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
- = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
ETextureIndex tex_index = baked_dict->mTextureIndex;
if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
@@ -10409,8 +10745,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
// print any avatar textures we didn't already know about
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -10463,10 +10799,178 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
{
mVisuallyMuteSetting = set;
mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 7;
LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
}
+
+void LLVOAvatar::setOverallAppearanceNormal()
+{
+ if (isControlAvatar())
+ return;
+
+ LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
+ resetSkeleton(false);
+ getJoint("mPelvis")->setPosition(pelvis_pos);
+
+ for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
+ {
+ bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+ LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+ if (!is_playing)
+ {
+ // Anim was not requested for this av by sim, but may be playing locally
+ stopMotion(*it);
+ }
+ }
+ mJellyAnims.clear();
+
+ processAnimationStateChanges();
+}
+
+void LLVOAvatar::setOverallAppearanceJellyDoll()
+{
+ if (isControlAvatar())
+ return;
+
+ // stop current animations
+ {
+ for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin();
+ anim_it != mPlayingAnimations.end();
+ ++anim_it)
+ {
+ {
+ stopMotion(anim_it->first, TRUE);
+ }
+ }
+ }
+ processAnimationStateChanges();
+
+ // Start any needed anims for jellydoll
+ updateOverallAppearanceAnimations();
+
+ LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
+ resetSkeleton(false);
+ getJoint("mPelvis")->setPosition(pelvis_pos);
+
+}
+
+void LLVOAvatar::setOverallAppearanceInvisible()
+{
+}
+
+void LLVOAvatar::updateOverallAppearance()
+{
+ AvatarOverallAppearance new_overall = getOverallAppearance();
+ if (new_overall != mOverallAppearance)
+ {
+ switch (new_overall)
+ {
+ case AOA_NORMAL:
+ setOverallAppearanceNormal();
+ break;
+ case AOA_JELLYDOLL:
+ setOverallAppearanceJellyDoll();
+ break;
+ case AOA_INVISIBLE:
+ setOverallAppearanceInvisible();
+ break;
+ }
+ mOverallAppearance = new_overall;
+ if (!isSelf())
+ {
+ mNeedsImpostorUpdate = TRUE;
+ mLastImpostorUpdateReason = 8;
+ }
+ updateMeshVisibility();
+ }
+
+ // This needs to be done even if overall appearance has not
+ // changed, since sit/stand status can be different.
+ updateOverallAppearanceAnimations();
+}
+
+void LLVOAvatar::updateOverallAppearanceAnimations()
+{
+ if (isControlAvatar())
+ return;
+
+ if (getOverallAppearance() == AOA_JELLYDOLL)
+ {
+ LLUUID motion_id;
+ if (isSitting() && getParent()) // sitting on object
+ {
+ motion_id = ANIM_AGENT_SIT_FEMALE;
+ }
+ else if (isSitting()) // sitting on ground
+ {
+ motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED;
+ }
+ else // standing
+ {
+ motion_id = ANIM_AGENT_STAND;
+ }
+ if (mJellyAnims.find(motion_id) == mJellyAnims.end())
+ {
+ for (auto it = mJellyAnims.begin(); it != mJellyAnims.end(); ++it)
+ {
+ bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+ LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+ if (!is_playing)
+ {
+ // Anim was not requested for this av by sim, but may be playing locally
+ stopMotion(*it, TRUE);
+ }
+ }
+ mJellyAnims.clear();
+
+ startMotion(motion_id);
+ mJellyAnims.insert(motion_id);
+
+ processAnimationStateChanges();
+ }
+ }
+}
+
+// Based on isVisuallyMuted(), but has 3 possible results.
+LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
+{
+ AvatarOverallAppearance result = AOA_NORMAL;
+
+ // Priority order (highest priority first)
+ // * own avatar is always drawn normally
+ // * if on the "always draw normally" list, draw them normally
+ // * if on the "always visually mute" list, show as jellydoll
+ // * if explicitly muted (blocked), show as invisible
+ // * check against the render cost and attachment limits - if too complex, show as jellydoll
+ if (isSelf())
+ {
+ result = AOA_NORMAL;
+ }
+ else // !isSelf()
+ {
+ if (isInMuteList())
+ {
+ result = AOA_INVISIBLE;
+ }
+ else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+ {
+ result = AOA_NORMAL;
+ }
+ else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
+ { // Always want to see this AV as an impostor
+ result = AOA_JELLYDOLL;
+ }
+ else if (isTooComplex())
+ {
+ result = AOA_JELLYDOLL;
+ }
+ }
+
+ return result;
+}
+
void LLVOAvatar::calcMutedAVColor()
{
LLColor4 new_color(mMutedAVColor);
@@ -10476,8 +10980,8 @@ void LLVOAvatar::calcMutedAVColor()
if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
{
// explicitly not-rendered avatars are light grey
- new_color = LLColor4::grey3;
- change_msg = " not rendered: color is grey3";
+ new_color = LLColor4::grey4;
+ change_msg = " not rendered: color is grey4";
}
else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them
{
@@ -10490,26 +10994,31 @@ void LLVOAvatar::calcMutedAVColor()
new_color = LLColor4::white;
change_msg = " simple imposter ";
}
+#ifdef COLORIZE_JELLYDOLLS
else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
- {
+ {
// select a color based on the first byte of the agents uuid so any muted agent is always the same color
F32 color_value = (F32) (av_id.mData[0]);
- F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f
+ F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f
- // Array of colors. These are arranged so only one RGB color changes between each step,
+ // Array of colors. These are arranged so only one RGB color changes between each step,
// and it loops back to red so there is an even distribution. It is not a heat map
- const S32 NUM_SPECTRUM_COLORS = 7;
+ const S32 NUM_SPECTRUM_COLORS = 7;
static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red };
-
- spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors
- S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index
- S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive)
+
+ spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors
+ S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index
+ S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive)
F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1)
-
- new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
- new_color.normalize();
- new_color *= 0.28f; // Tone it down
+ new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
+ new_color.normalize();
+ new_color *= 0.28f; // Tone it down
+ }
+#endif
+ else
+ {
+ new_color = LLColor4::grey4;
change_msg = " over limit color ";
}
@@ -10525,7 +11034,7 @@ BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
{
return (index < 0 || index >= TEX_NUM_INDICES)
? false
- : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture;
}
// static
@@ -10533,15 +11042,15 @@ BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
{
return (index < 0 || index >= TEX_NUM_INDICES)
? false
- : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture;
}
const std::string LLVOAvatar::getBakedStatusForPrintout() const
{
std::string line;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 00dccc5d12..74ef589ca4 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -91,6 +91,7 @@ class LLVOAvatar :
public:
friend class LLVOAvatarSelf;
+ friend class LLAvatarCheckImpostorMode;
/********************************************************************************
** **
@@ -131,6 +132,7 @@ protected:
public:
/*virtual*/ void updateGL();
/*virtual*/ LLVOAvatar* asAvatar();
+
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
@@ -252,6 +254,11 @@ public:
virtual bool isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)
virtual bool isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user)
+ // If this is an attachment, return the avatar it is attached to. Otherwise NULL.
+ virtual const LLVOAvatar *getAttachedAvatar() const { return NULL; }
+ virtual LLVOAvatar *getAttachedAvatar() { return NULL; }
+
+
private: //aligned members
LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
@@ -262,7 +269,8 @@ public:
void updateAppearanceMessageDebugText();
void updateAnimationDebugText();
virtual void updateDebugText();
- virtual BOOL updateCharacter(LLAgent &agent);
+ virtual bool computeNeedsUpdate();
+ virtual bool updateCharacter(LLAgent &agent);
void updateFootstepSounds();
void computeUpdatePeriod();
void updateOrientation(LLAgent &agent, F32 speed, F32 delta_time);
@@ -284,8 +292,9 @@ public:
static void invalidateNameTag(const LLUUID& agent_id);
// force all name tags to rebuild, useful when display names turned on/off
static void invalidateNameTags();
- void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
+ void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false);
void idleUpdateRenderComplexity();
+ void idleUpdateDebugInfo();
void accountRenderComplexityForObject(const LLViewerObject *attached_object,
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
@@ -313,12 +322,12 @@ public:
public:
static S32 sRenderName;
static BOOL sRenderGroupTitles;
- static const U32 IMPOSTORS_OFF; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
- * slider in panel_preferences_graphics1.xml */
- static U32 sMaxNonImpostors; //(affected by control "RenderAvatarMaxNonImpostors")
- static F32 sRenderDistance; //distance at which avatars will render.
+ static const U32 NON_IMPOSTORS_MAX_SLIDER; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
+ * slider in panel_preferences_graphics1.xml */
+ static U32 sMaxNonImpostors; // affected by control "RenderAvatarMaxNonImpostors"
+ 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 sUseImpostors; //use impostors for far away avatars
static BOOL sShowFootPlane; // show foot collision plane reported by server
static BOOL sShowCollisionVolumes; // show skeletal collision volumes
static BOOL sVisibleInFirstPerson;
@@ -348,7 +357,7 @@ public:
BOOL isFullyTextured() const;
BOOL hasGray() const;
S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
- void updateRezzedStatusTimers();
+ void updateRezzedStatusTimers(S32 status);
S32 mLastRezzedStatus;
@@ -406,6 +415,7 @@ public:
void initAttachmentPoints(bool ignore_hud_joints = false);
/*virtual*/ void buildCharacter();
void resetVisualParams();
+ void applyDefaultParams();
void resetSkeleton(bool reset_animations);
LLVector3 mCurRootToHeadOffset;
@@ -426,9 +436,12 @@ public:
public:
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
bool isVisuallyMuted();
- bool isInMuteList();
+ bool isInMuteList() const;
void forceUpdateVisualMuteSettings();
+ // Visual Mute Setting is an input. Does not necessarily determine
+ // what the avatar looks like, because it interacts with other
+ // settings like muting, complexity threshold. Should be private or protected.
enum VisualMuteSettings
{
AV_RENDER_NORMALLY = 0,
@@ -436,21 +449,50 @@ public:
AV_ALWAYS_RENDER = 2
};
void setVisualMuteSettings(VisualMuteSettings set);
+
+protected:
+ // If you think you need to access this outside LLVOAvatar, you probably want getOverallAppearance()
VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; };
+public:
+
+ // Overall Appearance is an output. Depending on whether the
+ // avatar is blocked/muted, whether it exceeds the complexity
+ // threshold, etc, avatar will want to be displayed in one of
+ // these ways. Rendering code that wants to know how to display an
+ // avatar should be looking at this value, NOT the visual mute
+ // settings
+ enum AvatarOverallAppearance
+ {
+ AOA_NORMAL,
+ AOA_JELLYDOLL,
+ AOA_INVISIBLE
+ };
+
+ AvatarOverallAppearance getOverallAppearance() const;
+ void setOverallAppearanceNormal();
+ void setOverallAppearanceJellyDoll();
+ void setOverallAppearanceInvisible();
+
+ void updateOverallAppearance();
+ void updateOverallAppearanceAnimations();
+
+ std::set<LLUUID> mJellyAnims;
+
U32 renderRigid();
U32 renderSkinned();
F32 getLastSkinTime() { return mLastSkinTime; }
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
- void renderBones();
+ void renderBones(const std::string &selected_joint = std::string());
void renderJoints();
static void deleteCachedImages(bool clearAll=true);
static void destroyGL();
static void restoreGL();
S32 mSpecialRenderMode; // special lighting
- private:
+private:
+ AvatarOverallAppearance mOverallAppearance;
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
U32 mAttachmentVisibleTriangleCount;
F32 mAttachmentEstTriangleCount;
@@ -467,8 +509,8 @@ public:
mutable bool mVisualComplexityStale;
U32 mReportedVisualComplexity; // from other viewers through the simulator
- bool mCachedInMuteList;
- F64 mCachedMuteListUpdateTime;
+ mutable bool mCachedInMuteList;
+ mutable F64 mCachedMuteListUpdateTime;
VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV
@@ -519,7 +561,7 @@ private:
//--------------------------------------------------------------------
public:
virtual BOOL isImpostor();
- BOOL shouldImpostor(const U32 rank_factor = 1) const;
+ BOOL shouldImpostor(const F32 rank_factor = 1.0);
BOOL needsImpostorUpdate() const;
const LLVector3& getImpostorOffset() const;
const LLVector2& getImpostorDim() const;
@@ -530,6 +572,7 @@ public:
static void updateImpostors();
LLRenderTarget mImpostor;
BOOL mNeedsImpostorUpdate;
+ S32 mLastImpostorUpdateReason;
F32SecondsImplicit mLastImpostorUpdateFrameTime;
const LLVector3* getLastAnimExtents() const { return mLastAnimExtents; }
void setNeedsExtentUpdate(bool val) { mNeedsExtentUpdate = val; }
@@ -629,6 +672,8 @@ protected:
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;
BOOL mLoadedCallbacksPaused;
+ S32 mLoadedCallbackTextures; // count of 'loaded' baked textures, filled from mCallbackTextureList
+ LLFrameTimer mLastTexCallbackAddedTime;
std::set<LLUUID> mTextureIDs;
//--------------------------------------------------------------------
// Local Textures
@@ -674,9 +719,6 @@ public:
public:
static BOOL isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i);
static BOOL isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i);
-private:
- static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
- static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
//--------------------------------------------------------------------
// Messaging
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 63ace4fe52..7faca2ee5b 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -465,6 +465,8 @@ BOOL LLVOAvatarSelf::buildMenus()
if (gDetachBodyPartPieMenus[i])
{
gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
+ gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
+ gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
}
else
{
@@ -493,12 +495,14 @@ BOOL LLVOAvatarSelf::buildMenus()
LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gDetachPieMenu->addChild(item);
-
+ gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
break;
}
}
}
}
+
// add screen attachments
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
@@ -532,6 +536,8 @@ BOOL LLVOAvatarSelf::buildMenus()
item_params.on_enable.parameter = iter->first;
item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
gDetachScreenPieMenu->addChild(item);
+ gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+ gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
}
}
@@ -668,7 +674,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
*********************************************************************************/
// virtual
-BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
+bool LLVOAvatarSelf::updateCharacter(LLAgent &agent)
{
// update screen joint size
if (mScreenp)
@@ -1079,8 +1085,8 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type)
{
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
@@ -1250,7 +1256,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
- gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
+ gMessageSystem->sendReliable(gAgent.getRegionHost());
// This object might have been selected, so let the selection manager know it's gone now
LLViewerObject *found_obj = gObjectList.findObject(item_id);
@@ -1277,7 +1283,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
{
- LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
return gAgentWearables.getWearableCount(type);
}
@@ -1388,8 +1394,8 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye
{
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -1402,7 +1408,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1432,13 +1438,13 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset
{
if (layerset == mBakedTextureDatas[i].mTexLayerSet)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1465,13 +1471,13 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1493,7 +1499,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex t
BOOL isDefined = TRUE;
if (isIndexLocalTexture(type))
{
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (index >= wearable_count)
{
@@ -1710,7 +1716,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL;
return;
}
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type);
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
if (!gAgentWearables.getViewerWearable(wearable_type,index))
{
// no wearable is loaded, cannot set the texture.
@@ -1787,8 +1793,8 @@ void LLVOAvatarSelf::dumpLocalTextures() const
/* ETextureIndex baked_equiv[] = {
TEX_UPPER_BAKED,
if (isTextureDefined(baked_equiv[i])) */
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -1796,7 +1802,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
continue;
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+ const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex;
const std::string &name = texture_dict->mName;
const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
@@ -2031,8 +2037,8 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
{
std::ostringstream outbuf;
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -2045,9 +2051,9 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName;
+ const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName;
outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n";
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (wearable_count > 0)
{
@@ -2091,8 +2097,8 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
void LLVOAvatarSelf::dumpAllTextures() const
{
std::string vd_text = "Local textures per baked index and wearable:\n";
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
@@ -2113,8 +2119,8 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTe
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -2127,7 +2133,7 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTe
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (wearable_count > 0)
{
@@ -2154,14 +2160,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
BOOL is_texture_final = TRUE;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -2341,7 +2347,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
{
if (canGrabBakedTexture(baked_index))
{
- ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return LLUUID::null;
@@ -2353,7 +2359,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
{
- ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return FALSE;
@@ -2372,13 +2378,13 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
// baked texture. We don't want people copying people's
// work via baked textures.
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index);
for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
iter != baked_dict->mLocalTextures.end();
++iter)
{
const ETextureIndex t_index = (*iter);
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index);
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index);
U32 count = gAgentWearables.getWearableCount(wearable_type);
LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL;
@@ -2466,7 +2472,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
{
- LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
if (wearable)
{
@@ -2540,8 +2546,8 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL;
}
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
@@ -2607,7 +2613,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
case LOCTEX_UPPER_SHIRT:
if( mUpperBodyLayerSet )
mUpperBodyLayerSet->requestUpdate(); */
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
if (!texture_dict)
return;
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
@@ -2625,7 +2631,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
case TEX_HEAD_BAKED:
case TEX_HEAD_BODYPAINT:
return mHeadLayerSet; */
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
if (texture_dict && texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2667,11 +2673,6 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
-
-#if 0
- gAgentAvatarp->clearVisualParamWeights();
- gAgentAvatarp->idleUpdateAppearanceAnimation();
-#endif
gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
@@ -2716,8 +2717,8 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
{
LLUUID texture_id[TEX_NUM_INDICES];
// pack away current TEs to make sure we don't send them out
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
@@ -2733,8 +2734,8 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
bool success = packTEMessage(mesgsys);
// unpack TEs to make sure we don't re-trigger a bake
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index b0fdae9bf0..279dbd61a6 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -116,7 +116,7 @@ public:
// Updates
//--------------------------------------------------------------------
public:
- /*virtual*/ BOOL updateCharacter(LLAgent &agent);
+ /*virtual*/ bool updateCharacter(LLAgent &agent);
/*virtual*/ void idleUpdateTractorBeam();
bool checkStuckAppearance();
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 07660ca6ac..689eeee0e3 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -347,36 +347,24 @@ void LLVOCacheEntry::dump() const
BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
{
- BOOL success;
- success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
- if(success)
- {
- success = check_write(apr_file, (void*)&mCRC, sizeof(U32));
- }
- if(success)
- {
- success = check_write(apr_file, (void*)&mHitCount, sizeof(S32));
- }
- if(success)
- {
- success = check_write(apr_file, (void*)&mDupeCount, sizeof(S32));
- }
- if(success)
- {
- success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32));
- }
- if(success)
- {
- S32 size = mDP.getBufferSize();
- success = check_write(apr_file, (void*)&size, sizeof(S32));
-
- if(success)
- {
- success = check_write(apr_file, (void*)mBuffer, size);
- }
- }
-
- return success ;
+ static const S32 data_buffer_size = 6 * sizeof(S32);
+ static U8 data_buffer[data_buffer_size];
+ S32 size = mDP.getBufferSize();
+
+ memcpy(data_buffer, &mLocalID, sizeof(U32));
+ memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32));
+ memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32));
+ memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32));
+ memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32));
+ memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32));
+
+ BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size);
+ if (success)
+ {
+ success = check_write(apr_file, (void*)mBuffer, size);
+ }
+
+ return success;
}
//static
@@ -1537,7 +1525,8 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
{
S32 num_entries = cache_entry_map.size() ;
success = check_write(&apr_file, &num_entries, sizeof(S32));
-
+
+ // This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
{
if(!removal_enabled || iter->second->isValid())
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index d651d540b9..345e87eea8 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -288,24 +288,12 @@ void LLVOGrass::idleUpdate(LLAgent &agent, const F64 &time)
// So drones work.
return;
}
-
- if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass
+ if (!LLVOTree::isTreeRenderingStopped() && !mNumBlades)//restart grass rendering
{
- if(mNumBlades)
- {
- mNumBlades = 0 ;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- }
- return;
- }
- else if(!mNumBlades)//restart grass rendering
- {
- mNumBlades = GRASS_MAX_BLADES ;
+ mNumBlades = GRASS_MAX_BLADES;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
-
return;
}
-
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
@@ -352,11 +340,15 @@ BOOL LLVOGrass::updateLOD()
{
return FALSE;
}
+
+ LLFace* face = mDrawable->getFace(0);
+
if(LLVOTree::isTreeRenderingStopped())
{
if(mNumBlades)
{
mNumBlades = 0 ;
+ face->setSize(0, 0);
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
return TRUE ;
@@ -366,8 +358,6 @@ BOOL LLVOGrass::updateLOD()
mNumBlades = GRASS_MAX_BLADES;
}
- LLFace* face = mDrawable->getFace(0);
-
F32 tan_angle = 0.f;
S32 num_blades = 0;
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 71a7623fb4..52a6395618 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -126,7 +126,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
left_dir.normVec();
// Our center top point
- LLColor4 ground_color = gSky.getFogColor();
+ LLColor4 ground_color = gSky.getSkyFogColor();
ground_color.mV[3] = 1.f;
face->setFaceColor(ground_color);
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index cc590fc947..e2bd1a39c7 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -180,6 +180,13 @@ void LLVoiceClient::terminate()
{
if (mVoiceModule) mVoiceModule->terminate();
mVoiceModule = NULL;
+ m_servicePump = NULL;
+
+ // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it
+ if (LLSpeakerVolumeStorage::instanceExists())
+ {
+ LLSpeakerVolumeStorage::deleteSingleton();
+ }
}
const LLVoiceVersionInfo LLVoiceClient::getVersion()
@@ -200,8 +207,6 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
void LLVoiceClient::updateSettings()
{
setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
- std::string keyString = gSavedSettings.getString("PushToTalkButton");
- setPTTKey(keyString);
setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle"));
mDisableMic = gSavedSettings.getBOOL("VoiceDisableMic");
@@ -637,32 +642,6 @@ bool LLVoiceClient::getPTTIsToggle()
return mPTTIsToggle;
}
-void LLVoiceClient::setPTTKey(std::string &key)
-{
- // Value is stored as text for readability
- if(key == "MiddleMouse")
- {
- mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE;
- }
- else if(key == "MouseButton4")
- {
- mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4;
- }
- else if (key == "MouseButton5")
- {
- mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5;
- }
- else
- {
- mPTTMouseButton = 0;
- if(!LLKeyboard::keyFromString(key, &mPTTKey))
- {
- // If the call failed, don't match any key.
- key = KEY_NONE;
- }
- }
-}
-
void LLVoiceClient::inputUserControlState(bool down)
{
if(mPTTIsToggle)
@@ -683,43 +662,6 @@ void LLVoiceClient::toggleUserPTTState(void)
setUserPTTState(!getUserPTTState());
}
-void LLVoiceClient::keyDown(KEY key, MASK mask)
-{
- if (gKeyboard->getKeyRepeated(key))
- {
- // ignore auto-repeat keys
- return;
- }
-
- if (mPTTMouseButton == 0 && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
- {
- bool down = gKeyboard->getKeyDown(mPTTKey);
- if (down)
- {
- inputUserControlState(down);
- }
- }
-
-}
-void LLVoiceClient::keyUp(KEY key, MASK mask)
-{
- if (mPTTMouseButton == 0 && (key == mPTTKey))
- {
- bool down = gKeyboard->getKeyDown(mPTTKey);
- if (!down)
- {
- inputUserControlState(down);
- }
- }
-}
-void LLVoiceClient::updateMouseState(S32 click, bool down)
-{
- if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak"))
- {
- inputUserControlState(down);
- }
-}
-
//-------------------------------------------
// nearby speaker accessors
@@ -981,7 +923,12 @@ LLSpeakerVolumeStorage::LLSpeakerVolumeStorage()
LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
{
- save();
+}
+
+//virtual
+void LLSpeakerVolumeStorage::cleanupSingleton()
+{
+ save();
}
void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 volume)
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 3d04e1f0db..cf527a4464 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -408,16 +408,10 @@ public:
void setUsePTT(bool usePTT);
void setPTTIsToggle(bool PTTIsToggle);
bool getPTTIsToggle();
- void setPTTKey(std::string &key);
-
+
void updateMicMuteLogic();
-
+
BOOL lipSyncEnabled();
-
- // PTT key triggering
- void keyDown(KEY key, MASK mask);
- void keyUp(KEY key, MASK mask);
- void updateMouseState(S32 click, bool down);
boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
@@ -499,9 +493,13 @@ protected:
**/
class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
{
- LLSINGLETON(LLSpeakerVolumeStorage);
+ LLSINGLETON_C11(LLSpeakerVolumeStorage);
~LLSpeakerVolumeStorage();
LOG_CLASS(LLSpeakerVolumeStorage);
+
+protected:
+ virtual void cleanupSingleton() override;
+
public:
/**
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 739f7bd47c..7d8aa6fbbd 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -274,6 +274,8 @@ static void killGateway()
///////////////////////////////////////////////////////////////////////////////////////////////
+bool LLVivoxVoiceClient::sShuttingDown = false;
+
LLVivoxVoiceClient::LLVivoxVoiceClient() :
mSessionTerminateRequested(false),
mRelogRequested(false),
@@ -338,15 +340,15 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mPlayRequestCount(0),
mAvatarNameCacheConnection(),
- mIsInTuningMode(false),
- mIsInChannel(false),
- mIsJoiningSession(false),
- mIsWaitingForFonts(false),
- mIsLoggingIn(false),
- mIsLoggedIn(false),
- mIsProcessingChannels(false),
- mIsCoroutineActive(false),
- mVivoxPump("vivoxClientPump")
+ mIsInTuningMode(false),
+ mIsInChannel(false),
+ mIsJoiningSession(false),
+ mIsWaitingForFonts(false),
+ mIsLoggingIn(false),
+ mIsLoggedIn(false),
+ mIsProcessingChannels(false),
+ mIsCoroutineActive(false),
+ mVivoxPump("vivoxClientPump")
{
mSpeakerVolume = scale_speaker_volume(0);
@@ -357,7 +359,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
// gMuteListp->addObserver(&mutelist_listener);
-#if LL_DARWIN || LL_LINUX || LL_SOLARIS
+#if LL_DARWIN || LL_LINUX
// HACK: THIS DOES NOT BELONG HERE
// When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us.
// This should cause us to ignore SIGPIPE and handle the error through proper channels.
@@ -381,6 +383,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
{
mAvatarNameCacheConnection.disconnect();
}
+ sShuttingDown = true;
}
//---------------------------------------------------
@@ -388,9 +391,9 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
void LLVivoxVoiceClient::init(LLPumpIO *pump)
{
// constructor will set up LLVoiceClient::getInstance()
- LLVivoxVoiceClient::getInstance()->mPump = pump;
+ mPump = pump;
-// LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+// LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
// boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
@@ -411,8 +414,12 @@ void LLVivoxVoiceClient::terminate()
}
else
{
+ mRelogRequested = false;
killGateway();
}
+
+ sShuttingDown = true;
+ mPump = NULL;
}
//---------------------------------------------------
@@ -527,7 +534,7 @@ void LLVivoxVoiceClient::connectorCreate()
<< "<FileNameSuffix>.log</FileNameSuffix>"
<< "<LogLevel>" << vivoxLogLevel << "</LogLevel>"
<< "</Logging>"
- << "<Application>" << LLVersionInfo::getChannel().c_str() << " " << LLVersionInfo::getVersion().c_str() << "</Application>"
+ << "<Application>" << LLVersionInfo::instance().getChannel() << " " << LLVersionInfo::instance().getVersion() << "</Application>"
//<< "<Application></Application>" //Name can cause problems per vivox.
<< "<MaxCalls>12</MaxCalls>"
<< "</Request>\n\n\n";
@@ -660,17 +667,38 @@ void LLVivoxVoiceClient::voiceControlCoro()
U32 retry = 0;
- while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && !sShuttingDown)
{
LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL;
llcoro::suspendUntilTimeout(1.0);
}
+ if (sShuttingDown)
+ {
+ mIsCoroutineActive = false;
+ return;
+ }
+
do
{
bool success = startAndConnectSession();
if (success)
{
+ // enable/disable the automatic VAD and explicitly set the initial values of
+ // the VAD variables ourselves when it is off - see SL-15072 for more details
+ // note: we set the other parameters too even if the auto VAD is on which is ok
+ unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto");
+ unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover");
+ unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor");
+ unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity");
+ setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity);
+
+ // watch for changes to the VAD settings via Debug Settings UI and act on them accordingly
+ gSavedSettings.getControl("VivoxVadAuto")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+ gSavedSettings.getControl("VivoxVadHangover")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+ gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+ gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+
if (mTuningMode)
{
performMicTuning();
@@ -691,7 +719,7 @@ void LLVivoxVoiceClient::voiceControlCoro()
<< "disconnected"
<< " RelogRequested=" << mRelogRequested
<< LL_ENDL;
- if (mRelogRequested)
+ if (mRelogRequested && !sShuttingDown)
{
if (!success)
{
@@ -706,14 +734,14 @@ void LLVivoxVoiceClient::voiceControlCoro()
LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL;
}
- while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ while (isGatewayRunning() || (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && !sShuttingDown))
{
LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL;
llcoro::suspendUntilTimeout(1.0);
}
}
}
- while (mVoiceEnabled && mRelogRequested);
+ while (mVoiceEnabled && mRelogRequested && !sShuttingDown);
mIsCoroutineActive = false;
LL_INFOS("Voice") << "exiting" << LL_ENDL;
}
@@ -758,7 +786,7 @@ bool LLVivoxVoiceClient::endAndDisconnectSession()
bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data)
{
- if (!LLAppViewer::isExiting() && mVoiceEnabled)
+ if (!sShuttingDown && mVoiceEnabled)
{
LL_WARNS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL;
terminateAudioSession(false);
@@ -806,6 +834,21 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
LLProcess::Params params;
params.executable = exe_path;
+ // VOICE-88: Cycle through [portbase..portbase+portrange) on
+ // successive tries because attempting to relaunch (after manually
+ // disabling and then re-enabling voice) with the same port can
+ // cause SLVoice's bind() call to fail with EADDRINUSE. We expect
+ // that eventually the OS will time out previous ports, which is
+ // why we cycle instead of incrementing indefinitely.
+ U32 portbase = gSavedSettings.getU32("VivoxVoicePort");
+ static U32 portoffset = 0;
+ static const U32 portrange = 100;
+ std::string host(gSavedSettings.getString("VivoxVoiceHost"));
+ U32 port = portbase + portoffset;
+ portoffset = (portoffset + 1) % portrange;
+ params.args.add("-i");
+ params.args.add(STRINGIZE(host << ':' << port));
+
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
if (loglevel.empty())
{
@@ -862,7 +905,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
sGatewayPtr = LLProcess::create(params);
- mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
+ mDaemonHost = LLHost(host.c_str(), port);
}
else
{
@@ -900,7 +943,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
LL_DEBUGS("Voice") << "Connecting to vivox daemon:" << mDaemonHost << LL_ENDL;
LLVoiceVivoxStats::getInstance()->reset();
- while (!mConnected)
+ while (!mConnected && !sShuttingDown)
{
LLVoiceVivoxStats::getInstance()->connectionAttemptStart();
LL_DEBUGS("Voice") << "Attempting to connect to vivox daemon: " << mDaemonHost << LL_ENDL;
@@ -919,12 +962,22 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
}
//---------------------------------------------------------------------
+ if (sShuttingDown && !mConnected)
+ {
+ return false;
+ }
+
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
- while (!mPump)
- { // Can't do this until we have the pump available.
+ while (!mPump && !sShuttingDown)
+ { // Can't use the pump until we have it available.
llcoro::suspend();
}
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
// MBW -- Note to self: pumps and pipes examples in
// indra/test/io.cpp
@@ -937,8 +990,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket)));
readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser()));
+
mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
+
//---------------------------------------------------------------------
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
@@ -955,12 +1010,17 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
{
LL_INFOS("Voice") << "Provisioning voice account." << LL_ENDL;
- while (!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived())
+ while ((!gAgent.getRegion() || !gAgent.getRegion()->capabilitiesReceived()) && !sShuttingDown)
{
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
// *TODO* Pump a message for wake up.
llcoro::suspend();
}
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest");
@@ -999,10 +1059,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
{
provisioned = true;
}
- } while (!provisioned && retryCount <= PROVISION_RETRY_MAX);
+ } while (!provisioned && retryCount <= PROVISION_RETRY_MAX && !sShuttingDown);
+
+ if (sShuttingDown && !provisioned)
+ {
+ return false;
+ }
LLVoiceVivoxStats::getInstance()->provisionAttemptEnd(provisioned);
- if (! provisioned )
+ if (!provisioned)
{
LL_WARNS("Voice") << "Could not access voice provision cap after " << retryCount << " attempts." << LL_ENDL;
return false;
@@ -1038,13 +1103,16 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
bool LLVivoxVoiceClient::establishVoiceConnection()
{
- LLEventPump &voiceConnectPump = LLEventPumps::instance().obtain("vivoxClientPump");
-
if (!mVoiceEnabled && mIsInitialized)
{
LL_WARNS("Voice") << "cannot establish connection; enabled "<<mVoiceEnabled<<" initialized "<<mIsInitialized<<LL_ENDL;
return false;
}
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
LLSD result;
bool connected(false);
@@ -1056,7 +1124,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
connectorCreate();
do
{
- result = llcoro::suspendUntilEventOn(voiceConnectPump);
+ result = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("connector"))
@@ -1065,7 +1133,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
connected = LLSD::Boolean(result["connector"]);
if (!connected)
{
- if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX)
+ if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX && !sShuttingDown)
{
F32 timeout = LLSD::Real(result["retry"]);
timeout *= retries;
@@ -1093,7 +1161,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
LL_DEBUGS("Voice") << (connected ? "" : "not ") << "connected, "
<< (giving_up ? "" : "not ") << "giving up"
<< LL_ENDL;
- } while (!connected && !giving_up);
+ } while (!connected && !giving_up && !sShuttingDown);
if (giving_up)
{
@@ -1108,7 +1176,6 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
LL_DEBUGS("Voice") << "( wait=" << corowait << ")" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
bool retval(true);
mShutdownComplete = false;
@@ -1118,7 +1185,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
LLSD timeoutResult(LLSDMap("connector", "timeout"));
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
retval = result.has("connector");
@@ -1140,7 +1207,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
mConnected = false;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
mShutdownComplete = true;
}
@@ -1157,8 +1224,6 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
bool LLVivoxVoiceClient::loginToVivox()
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
-
LLSD timeoutResult(LLSDMap("login", "timeout"));
int loginRetryCount(0);
@@ -1176,14 +1241,14 @@ bool LLVivoxVoiceClient::loginToVivox()
send_login = false;
}
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("login"))
{
std::string loginresp = result["login"];
- if ((loginresp == "retry") || (loginresp == "timeout"))
+ if (((loginresp == "retry") || (loginresp == "timeout")) && !sShuttingDown)
{
LL_WARNS("Voice") << "login failed with status '" << loginresp << "' "
<< " count " << loginRetryCount << "/" << LOGIN_RETRY_MAX
@@ -1225,9 +1290,14 @@ bool LLVivoxVoiceClient::loginToVivox()
{
account_login = true;
}
+ else if (sShuttingDown)
+ {
+ mIsLoggingIn = false;
+ return false;
+ }
}
- } while (!response_ok || !account_login);
+ } while ((!response_ok || !account_login) && !sShuttingDown);
mRelogRequested = false;
mIsLoggedIn = true;
@@ -1259,17 +1329,23 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
if (wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD timeoutResult(LLSDMap("logout", "timeout"));
+ LLSD result;
- LL_DEBUGS("Voice")
- << "waiting for logout response on "
- << voicePump.getName()
- << LL_ENDL;
-
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
-
- LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
+ do
+ {
+ LL_DEBUGS("Voice")
+ << "waiting for logout response on "
+ << mVivoxPump.getName()
+ << LL_ENDL;
+
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+
+ LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
+ // Don't get confused by prior queued events -- note that it's
+ // very important that mVivoxPump is an LLEventMailDrop, which
+ // does queue events.
+ } while (! result["logout"]);
}
else
{
@@ -1283,8 +1359,6 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
bool LLVivoxVoiceClient::retrieveVoiceFonts()
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
-
// Request the set of available voice fonts.
refreshVoiceEffectLists(true);
@@ -1292,7 +1366,7 @@ bool LLVivoxVoiceClient::retrieveVoiceFonts()
LLSD result;
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("voice_fonts"))
@@ -1408,7 +1482,6 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
mIsJoiningSession = true;
sessionStatePtr_t oldSession = mAudioSession;
@@ -1497,7 +1570,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
// We are about to start a whole new session. Anything that MIGHT still be in our
// maildrop is going to be stale and cause us much wailing and gnashing of teeth.
// Just flush it all out and start new.
- voicePump.flush();
+ mVivoxPump.discard();
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
// before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
@@ -1505,7 +1578,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
// This is a cheap way to make sure both have happened before proceeding.
do
{
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, SESSION_JOIN_TIMEOUT, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, SESSION_JOIN_TIMEOUT, timeoutResult);
LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1619,13 +1692,12 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
if (wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
do
{
LLSD timeoutResult(LLSDMap("session", "timeout"));
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1678,12 +1750,12 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
// the region chat.
mSessionTerminateRequested = false;
- bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting());
+ bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !sShuttingDown);
LL_DEBUGS("Voice") << "exiting"
<< " VoiceEnabled " << mVoiceEnabled
<< " IsInitialized " << mIsInitialized
<< " RelogRequested " << mRelogRequested
- << " AppExiting " << LLApp::isExiting()
+ << " ShuttingDown " << (sShuttingDown ? "TRUE" : "FALSE")
<< " returning " << status
<< LL_ENDL;
return status;
@@ -1700,6 +1772,12 @@ bool LLVivoxVoiceClient::waitForChannel()
return false;
}
+ if (sShuttingDown)
+ {
+ logoutOfVivox(true);
+ return false;
+ }
+
if (LLVoiceClient::instance().getVoiceEffectEnabled())
{
retrieveVoiceFonts();
@@ -1721,6 +1799,12 @@ bool LLVivoxVoiceClient::waitForChannel()
mIsProcessingChannels = true;
llcoro::suspend();
+ if (sShuttingDown)
+ {
+ mRelogRequested = false;
+ break;
+ }
+
if (mTuningMode)
{
performMicTuning();
@@ -1765,7 +1849,14 @@ bool LLVivoxVoiceClient::waitForChannel()
{
llcoro::suspendUntilTimeout(1.0);
}
- } while (mVoiceEnabled && !mRelogRequested);
+
+ if (sShuttingDown)
+ {
+ mRelogRequested = false;
+ break;
+ }
+
+ } while (mVoiceEnabled && !mRelogRequested && !sShuttingDown);
LL_DEBUGS("Voice")
<< "leaving inner waitForChannel loop"
@@ -1787,14 +1878,14 @@ bool LLVivoxVoiceClient::waitForChannel()
return false;
}
}
- } while (mVoiceEnabled && mRelogRequested && isGatewayRunning());
+ } while (mVoiceEnabled && mRelogRequested && isGatewayRunning() && !sShuttingDown);
LL_DEBUGS("Voice")
<< "exiting"
<< " RelogRequested=" << mRelogRequested
<< " VoiceEnabled=" << mVoiceEnabled
<< LL_ENDL;
- return true;
+ return !sShuttingDown;
}
bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
@@ -1822,7 +1913,6 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true)));
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
mIsInChannel = true;
mMuteMicDirty = true;
@@ -1874,7 +1964,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
sendLocalAudioUpdates();
mIsInitialized = true;
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
if (!result.has("timeout")) // logging the timeout event spams the log
{
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
@@ -1945,14 +2035,13 @@ void LLVivoxVoiceClient::sendCaptureAndRenderDevices()
void LLVivoxVoiceClient::recordingAndPlaybackMode()
{
LL_INFOS("Voice") << "In voice capture/playback mode." << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
while (true)
{
LLSD command;
do
{
- command = llcoro::suspendUntilEventOn(voicePump);
+ command = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(command) << LL_ENDL;
} while (!command.has("recplay"));
@@ -1985,7 +2074,6 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
captureBufferRecordStartSendMessage();
@@ -1993,7 +2081,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
do
{
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2015,7 +2103,6 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
do
@@ -2030,7 +2117,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
// Update UI, should really use a separate callback.
notifyVoiceFontObservers();
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2551,7 +2638,7 @@ void LLVivoxVoiceClient::tuningStart()
mTuningMode = true;
if (!mIsCoroutineActive)
{
- LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+ LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
else if (mIsInChannel)
@@ -3158,6 +3245,73 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
}
}
+/**
+ * Because of the recurring voice cutout issues (SL-15072) we are going to try
+ * to disable the automatic VAD (Voice Activity Detection) and set the associated
+ * parameters directly. We will expose them via Debug Settings and that should
+ * let us iterate on a collection of values that work for us. Hopefully!
+ *
+ * From the VIVOX Docs:
+ *
+ * VadAuto: A flag indicating if the automatic VAD is enabled (1) or disabled (0)
+ *
+ * VadHangover: The time (in milliseconds) that it takes
+ * for the VAD to switch back to silence from speech mode after the last speech
+ * frame has been detected.
+ *
+ * VadNoiseFloor: A dimensionless value between 0 and
+ * 20000 (default 576) that controls the maximum level at which the noise floor
+ * may be set at by the VAD's noise tracking. Too low of a value will make noise
+ * tracking ineffective (A value of 0 disables noise tracking and the VAD then
+ * relies purely on the sensitivity property). Too high of a value will make
+ * long speech classifiable as noise.
+ *
+ * VadSensitivity: A dimensionless value between 0 and
+ * 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds
+ * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive,
+ * while 100 is 'least sensitive')
+ */
+void LLVivoxVoiceClient::setupVADParams(unsigned int vad_auto,
+ unsigned int vad_hangover,
+ unsigned int vad_noise_floor,
+ unsigned int vad_sensitivity)
+{
+ std::ostringstream stream;
+
+ LL_INFOS("Voice") << "Setting the automatic VAD to "
+ << (vad_auto ? "True" : "False")
+ << " and discrete values to"
+ << " VadHangover = " << vad_hangover
+ << ", VadSensitivity = " << vad_sensitivity
+ << ", VadNoiseFloor = " << vad_noise_floor
+ << LL_ENDL;
+
+ // Create a request to set the VAD parameters:
+ stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetVadProperties.1\">"
+ << "<VadAuto>" << vad_auto << "</VadAuto>"
+ << "<VadHangover>" << vad_hangover << "</VadHangover>"
+ << "<VadSensitivity>" << vad_sensitivity << "</VadSensitivity>"
+ << "<VadNoiseFloor>" << vad_noise_floor << "</VadNoiseFloor>"
+ << "</Request>\n\n\n";
+
+ if (!stream.str().empty())
+ {
+ writeString(stream.str());
+ }
+}
+
+void LLVivoxVoiceClient::onVADSettingsChange()
+{
+ // pick up the VAD variables (one of which was changed)
+ unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto");
+ unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover");
+ unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor");
+ unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity");
+
+ // build a VAD params change request and send it to SLVoice
+ setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity);
+}
+
/////////////////////////////
// Response/Event handlers
@@ -3214,7 +3368,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st
result["connector"] = LLSD::Boolean(false);
}
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases)
@@ -3244,7 +3398,7 @@ void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString
result["login"] = LLSD::String("response_ok");
}
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
@@ -3270,7 +3424,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
("session", "failed")
("reason", LLSD::Integer(statusCode)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
else
{
@@ -3288,7 +3442,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "created"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3313,7 +3467,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "failed"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
else
{
@@ -3332,7 +3486,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "added"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3375,7 +3529,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin
}
LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &statusString)
@@ -3391,7 +3545,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
void LLVivoxVoiceClient::sessionAddedEvent(
@@ -3500,7 +3654,7 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
("session", "joined"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
// Add the current user as a participant here.
participantStatePtr_t participant(session->addParticipant(sipURIFromName(mAccountName)));
@@ -3644,7 +3798,7 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
("session", "removed"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3672,7 +3826,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 1:
levent["login"] = LLSD::String("account_login");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
case 2:
break;
@@ -3680,7 +3834,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 3:
levent["login"] = LLSD::String("account_loggingOut");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
case 4:
@@ -3693,7 +3847,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 0:
levent["login"] = LLSD::String("account_logout");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
default:
@@ -3728,7 +3882,7 @@ void LLVivoxVoiceClient::mediaCompletionEvent(std::string &sessionGroupHandle, s
}
if (!result.isUndefined())
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
@@ -5146,7 +5300,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
if (!mIsCoroutineActive)
{
- LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+ LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
else
@@ -5158,6 +5312,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
{
// Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it.
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
+ gAgent.setVoiceConnected(false);
status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
}
@@ -6540,7 +6695,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
// receiving the last one.
LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true)));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
notifyVoiceFontObservers();
mVoiceFontsReceived = true;
@@ -6691,7 +6846,7 @@ void LLVivoxVoiceClient::enablePreviewBuffer(bool enable)
else
result["recplay"] = "quit";
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
if(mCaptureBufferMode && mIsInChannel)
{
@@ -6712,7 +6867,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer()
mCaptureBufferRecording = true;
LLSD result(LLSDMap("recplay", "record"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
@@ -6735,7 +6890,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
mCaptureBufferPlaying = true;
LLSD result(LLSDMap("recplay", "playback"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::stopPreviewBuffer()
@@ -6744,7 +6899,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer()
mCaptureBufferPlaying = false;
LLSD result(LLSDMap("recplay", "quit"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
bool LLVivoxVoiceClient::isPreviewRecording()
@@ -7509,6 +7664,18 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->accountGetTemplateFontsResponse(statusCode, statusString);
}
+ else if (!stricmp(actionCstr, "Aux.SetVadProperties.1"))
+ {
+ // both values of statusCode (old and more recent) indicate valid requests
+ if (statusCode != 0 && statusCode != 200)
+ {
+ LL_WARNS("Voice") << "Aux.SetVadProperties.1 request failed: "
+ << "statusCode: " << statusCode
+ << " and "
+ << "statusString: " << statusString
+ << LL_ENDL;
+ }
+ }
/*
else if (!stricmp(actionCstr, "Account.ChannelGetList.1"))
{
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 210c726452..746201af04 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -473,6 +473,12 @@ protected:
void muteListChanged();
/////////////////////////////
+ // VAD changes
+ // disable auto-VAD and configure VAD parameters explicitly
+ void setupVADParams(unsigned int vad_auto, unsigned int vad_hangover, unsigned int vad_noise_floor, unsigned int vad_sensitivity);
+ void onVADSettingsChange();
+
+ /////////////////////////////
// Sending updates of current state
void updatePosition(void);
void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
@@ -912,6 +918,8 @@ private:
bool mIsProcessingChannels;
bool mIsCoroutineActive;
+ static bool sShuttingDown; // corutines can last longer than vivox so we need a static variable as a shutdown flag
+
LLEventMailDrop mVivoxPump;
};
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index c131cb886f..878d7287ed 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -48,170 +48,63 @@
#include "llworld.h"
#include "pipeline.h"
#include "lldrawpoolwlsky.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
+#include "v3colorutil.h"
+
+#include "llsettingssky.h"
+#include "llenvironment.h"
+
+#include "lltrace.h"
+#include "llfasttimer.h"
#undef min
#undef max
-static const S32 NUM_TILES_X = 8;
-static const S32 NUM_TILES_Y = 4;
-static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
+namespace
+{
+ const S32 NUM_TILES_X = 8;
+ const S32 NUM_TILES_Y = 4;
+ const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
+ const S32 NUM_CUBEMAP_FACES = 6;
// Heavenly body constants
-static const F32 SUN_DISK_RADIUS = 0.5f;
-static const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
-static const F32 SUN_INTENSITY = 1e5;
+ const F32 SUN_DISK_RADIUS = 0.5f;
+ const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
+ const F32 SUN_INTENSITY = 1e5;
// Texture coordinates:
-static const LLVector2 TEX00 = LLVector2(0.f, 0.f);
-static const LLVector2 TEX01 = LLVector2(0.f, 1.f);
-static const LLVector2 TEX10 = LLVector2(1.f, 0.f);
-static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
+ const LLVector2 TEX00 = LLVector2(0.f, 0.f);
+ const LLVector2 TEX01 = LLVector2(0.f, 1.f);
+ const LLVector2 TEX10 = LLVector2(1.f, 0.f);
+ const LLVector2 TEX11 = LLVector2(1.f, 1.f);
-// Exported globals
-LLUUID gSunTextureID = IMG_SUN;
-LLUUID gMoonTextureID = IMG_MOON;
-
-class LLFastLn
-{
-public:
- LLFastLn()
- {
- mTable[0] = 0;
- for( S32 i = 1; i < 257; i++ )
- {
- mTable[i] = log((F32)i);
- }
- }
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick");
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_CALC("VOSky Update Calculations");
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_CREATETEXTURES("VOSky Update Textures");
+ LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced");
- F32 ln( F32 x )
- {
- const F32 OO_255 = 0.003921568627450980392156862745098f;
- const F32 LN_255 = 5.5412635451584261462455391880218f;
+ F32Seconds UPDATE_EXPRY(0.25f);
- if( x < OO_255 )
- {
- return log(x);
- }
- else
- if( x < 1 )
- {
- x *= 255.f;
- S32 index = llfloor(x);
- F32 t = x - index;
- F32 low = mTable[index];
- F32 high = mTable[index + 1];
- return low + t * (high - low) - LN_255;
- }
- else
- if( x <= 255 )
- {
- S32 index = llfloor(x);
- F32 t = x - index;
- F32 low = mTable[index];
- F32 high = mTable[index + 1];
- return low + t * (high - low);
- }
- else
- {
- return log( x );
- }
- }
-
- F32 pow( F32 x, F32 y )
- {
- return (F32)LL_FAST_EXP(y * ln(x));
- }
-
-
-private:
- F32 mTable[257]; // index 0 is unused
-};
-
-static LLFastLn gFastLn;
-
-
-// Functions used a lot.
-
-inline F32 LLHaze::calcPhase(const F32 cos_theta) const
-{
- const F32 g2 = mG * mG;
- const F32 den = 1 + g2 - 2 * mG * cos_theta;
- return (1 - g2) * gFastLn.pow(den, -1.5);
+ const F32 UPDATE_MIN_DELTA_THRESHOLD = 0.0005f;
}
-
-inline void color_pow(LLColor3 &col, const F32 e)
-{
- col.mV[0] = gFastLn.pow(col.mV[0], e);
- col.mV[1] = gFastLn.pow(col.mV[1], e);
- col.mV[2] = gFastLn.pow(col.mV[2], e);
-}
-
-inline LLColor3 color_norm(const LLColor3 &col)
-{
- const F32 m = color_max(col);
- if (m > 1.f)
- {
- return 1.f/m * col;
- }
- else return col;
-}
-
-inline void color_gamma_correct(LLColor3 &col)
-{
- const F32 gamma_inv = 1.f/1.2f;
- if (col.mV[0] != 0.f)
- {
- col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv);
- }
- if (col.mV[1] != 0.f)
- {
- col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv);
- }
- if (col.mV[2] != 0.f)
- {
- col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv);
- }
-}
-
-static LLColor3 calc_air_sca_sea_level()
-{
- static LLColor3 WAVE_LEN(675, 520, 445);
- static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN);
- static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1);
- static LLColor3 n4 = n21 * n21;
- static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f;
- static LLColor3 wl4 = wl2 * wl2;
- static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4;
- static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2);
- return dens_div_N * color_div ( mult_const, wl4 );
-}
-
-// static constants.
-LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level();
-F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);
-F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f;
-
-
/***************************************
SkyTex
***************************************/
S32 LLSkyTex::sComponents = 4;
S32 LLSkyTex::sResolution = 64;
-F32 LLSkyTex::sInterpVal = 0.f;
S32 LLSkyTex::sCurrent = 0;
LLSkyTex::LLSkyTex() :
mSkyData(NULL),
- mSkyDirs(NULL)
+ mSkyDirs(NULL),
+ mIsShiny(false)
{
}
-void LLSkyTex::init()
+void LLSkyTex::init(bool isShiny)
{
+ mIsShiny = isShiny;
mSkyData = new LLColor4[sResolution * sResolution];
mSkyDirs = new LLVector3[sResolution * sResolution];
@@ -249,6 +142,32 @@ LLSkyTex::~LLSkyTex()
mSkyDirs = NULL;
}
+S32 LLSkyTex::getResolution()
+{
+ return sResolution;
+}
+
+S32 LLSkyTex::getCurrent()
+{
+ return sCurrent;
+}
+
+S32 LLSkyTex::stepCurrent() {
+ sCurrent++;
+ sCurrent &= 1;
+ return sCurrent;
+}
+
+S32 LLSkyTex::getNext()
+{
+ return ((sCurrent+1) & 1);
+}
+
+S32 LLSkyTex::getWhich(const BOOL curr)
+{
+ int tex = curr ? sCurrent : getNext();
+ return tex;
+}
void LLSkyTex::initEmpty(const S32 tex)
{
@@ -271,9 +190,8 @@ void LLSkyTex::initEmpty(const S32 tex)
createGLImage(tex);
}
-void LLSkyTex::create(const F32 brightness)
+void LLSkyTex::create()
{
- /// Brightness ignored for now.
U8* data = mImageRaw[sCurrent]->getData();
for (S32 i = 0; i < sResolution; ++i)
{
@@ -289,26 +207,195 @@ void LLSkyTex::create(const F32 brightness)
createGLImage(sCurrent);
}
-
-
-
void LLSkyTex::createGLImage(S32 which)
{
+ mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
void LLSkyTex::bindTexture(BOOL curr)
{
- gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true);
+ int tex = getWhich(curr);
+ gGL.getTexUnit(0)->bind(mTexture[tex], true);
+}
+
+LLImageRaw* LLSkyTex::getImageRaw(BOOL curr)
+{
+ int tex = getWhich(curr);
+ return mImageRaw[tex];
}
/***************************************
- Sky
+ LLHeavenBody
***************************************/
F32 LLHeavenBody::sInterpVal = 0;
+LLHeavenBody::LLHeavenBody(const F32 rad)
+: mDirectionCached(LLVector3(0,0,0)),
+ mDirection(LLVector3(0,0,0)),
+ mIntensity(0.f),
+ mDiskRadius(rad),
+ mDraw(FALSE),
+ mHorizonVisibility(1.f),
+ mVisibility(1.f),
+ mVisible(FALSE)
+{
+ mColor.setToBlack();
+ mColorCached.setToBlack();
+}
+
+const LLQuaternion& LLHeavenBody::getRotation() const
+{
+ return mRotation;
+}
+
+void LLHeavenBody::setRotation(const LLQuaternion& rot)
+{
+ mRotation = rot;
+}
+
+const LLVector3& LLHeavenBody::getDirection() const
+{
+ return mDirection;
+}
+
+void LLHeavenBody::setDirection(const LLVector3 &direction)
+{
+ mDirection = direction;
+}
+
+void LLHeavenBody::setAngularVelocity(const LLVector3 &ang_vel)
+{
+ mAngularVelocity = ang_vel;
+}
+
+const LLVector3& LLHeavenBody::getAngularVelocity() const
+{
+ return mAngularVelocity;
+}
+
+const LLVector3& LLHeavenBody::getDirectionCached() const
+{
+ return mDirectionCached;
+}
+
+void LLHeavenBody::renewDirection()
+{
+ mDirectionCached = mDirection;
+}
+
+const LLColor3& LLHeavenBody::getColorCached() const
+{
+ return mColorCached;
+}
+
+void LLHeavenBody::setColorCached(const LLColor3& c)
+{
+ mColorCached = c;
+}
+
+const LLColor3& LLHeavenBody::getColor() const
+{
+ return mColor;
+}
+
+void LLHeavenBody::setColor(const LLColor3& c)
+{
+ mColor = c;
+}
+
+void LLHeavenBody::renewColor()
+{
+ mColorCached = mColor;
+}
+
+F32 LLHeavenBody::interpVal()
+{
+ return sInterpVal;
+}
+
+void LLHeavenBody::setInterpVal(const F32 v)
+{
+ sInterpVal = v;
+}
+
+LLColor3 LLHeavenBody::getInterpColor() const
+{
+ return sInterpVal * mColor + (1 - sInterpVal) * mColorCached;
+}
+
+const F32& LLHeavenBody::getVisibility() const
+{
+ return mVisibility;
+}
+
+void LLHeavenBody::setVisibility(const F32 c)
+{
+ mVisibility = c;
+}
+
+bool LLHeavenBody::isVisible() const
+{
+ return mVisible;
+}
+
+void LLHeavenBody::setVisible(const bool v)
+{
+ mVisible = v;
+}
+
+const F32& LLHeavenBody::getIntensity() const
+{
+ return mIntensity;
+}
+
+void LLHeavenBody::setIntensity(const F32 c)
+{
+ mIntensity = c;
+}
+
+void LLHeavenBody::setDiskRadius(const F32 radius)
+{
+ mDiskRadius = radius;
+}
+
+F32 LLHeavenBody::getDiskRadius() const
+{
+ return mDiskRadius;
+}
+
+void LLHeavenBody::setDraw(const bool draw)
+{
+ mDraw = draw;
+}
+
+bool LLHeavenBody::getDraw() const
+{
+ return mDraw;
+}
+
+const LLVector3& LLHeavenBody::corner(const S32 n) const
+{
+ return mQuadCorner[n];
+}
+
+LLVector3& LLHeavenBody::corner(const S32 n)
+{
+ return mQuadCorner[n];
+}
+
+const LLVector3* LLHeavenBody::corners() const
+{
+ return mQuadCorner;
+}
+
+/***************************************
+ Sky
+***************************************/
+
+
S32 LLVOSky::sResolution = LLSkyTex::getResolution();
S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X;
S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y;
@@ -323,39 +410,24 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
mCloudDensity(0.2f),
mWind(0.f),
mForceUpdate(FALSE),
+ mNeedUpdate(TRUE),
+ mCubeMapUpdateStage(-1),
mWorldScale(1.f),
mBumpSunDir(0.f, 0.f, 1.f)
{
- bool error = false;
-
/// WL PARAMS
- dome_radius = 1.f;
- dome_offset_ratio = 0.f;
- sunlight_color = LLColor3();
- ambient = LLColor3();
- gamma = 1.f;
- lightnorm = LLVector4();
- blue_density = LLColor3();
- blue_horizon = LLColor3();
- haze_density = 0.f;
- haze_horizon = 1.f;
- density_multiplier = 0.f;
- max_y = 0.f;
- glow = LLColor3();
- cloud_shadow = 0.f;
- cloud_color = LLColor3();
- cloud_scale = 0.f;
- cloud_pos_density1 = LLColor3();
- cloud_pos_density2 = LLColor3();
mInitialized = FALSE;
mbCanSelect = FALSE;
mUpdateTimer.reset();
- for (S32 i = 0; i < 6; i++)
+ mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY);
+ mForceUpdateThrottle.reset();
+
+ for (S32 i = 0; i < NUM_CUBEMAP_FACES; i++)
{
- mSkyTex[i].init();
- mShinyTex[i].init();
+ mSkyTex[i].init(false);
+ mShinyTex[i].init(true);
}
for (S32 i=0; i<FACE_COUNT; i++)
{
@@ -366,32 +438,12 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
mAtmHeight = ATM_HEIGHT;
mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
- mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error));
- if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition"))
- {
- initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0));
- }
- mAmbientScale = gSavedSettings.getF32("SkyAmbientScale");
- mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift");
- mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
- mFogColor.mV[VALPHA] = 0.0f;
- mFogRatio = 1.2f;
-
mSun.setIntensity(SUN_INTENSITY);
mMoon.setIntensity(0.1f * SUN_INTENSITY);
- mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
- mBloomTexturep->setNoDelete() ;
- mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
mHeavenlyBodyUpdated = FALSE ;
mDrawRefl = 0;
- mHazeConcentration = 0.f;
mInterpVal = 0.f;
}
@@ -406,50 +458,107 @@ LLVOSky::~LLVOSky()
void LLVOSky::init()
{
- const F32 haze_int = color_intens(mHaze.calcSigSca(0));
- mHazeConcentration = haze_int /
- (color_intens(LLHaze::calcAirSca(0)) + haze_int);
-
- calcAtmospherics();
+ llassert(!mInitialized);
+
+ // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed
+ LLEnvironment::instance().getCurrentSky()->update();
+
+ updateDirections();
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ // invariants across whole sky tex process...
+ m_atmosphericsVars.blue_density = psky->getBlueDensity();
+ m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
+ m_atmosphericsVars.haze_density = psky->getHazeDensity();
+ m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
+ m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
+ m_atmosphericsVars.max_y = psky->getMaxY();
+ m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
+ m_atmosphericsVars.ambient = psky->getAmbientColor();
+ m_atmosphericsVars.glow = psky->getGlow();
+ m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
+ m_atmosphericsVars.dome_radius = psky->getDomeRadius();
+ m_atmosphericsVars.dome_offset = psky->getDomeOffset();
+ m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
+ m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
+ m_atmosphericsVars.total_density = psky->getTotalDensity();
+ m_atmosphericsVars.gamma = psky->getGamma();
// Initialize the cached normalized direction vectors
- for (S32 side = 0; side < 6; ++side)
+ for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
{
for (S32 tile = 0; tile < NUM_TILES; ++tile)
{
initSkyTextureDirs(side, tile);
- createSkyTexture(side, tile);
+ createSkyTexture(m_atmosphericsVars, side, tile);
}
- }
-
- for (S32 i = 0; i < 6; ++i)
- {
- mSkyTex[i].create(1.0f);
- mShinyTex[i].create(1.0f);
+ mSkyTex[side].create();
+ mShinyTex[side].create();
}
initCubeMap();
+
mInitialized = true;
mHeavenlyBodyUpdated = FALSE ;
+
+ mRainbowMap = LLViewerTextureManager::getFetchedTexture(psky->getRainbowTextureId(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mHaloMap = LLViewerTextureManager::getFetchedTexture(psky->getHaloTextureId(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+}
+
+
+void LLVOSky::calc()
+{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ // invariants across whole sky tex process...
+ m_atmosphericsVars.blue_density = psky->getBlueDensity();
+ m_atmosphericsVars.blue_horizon = psky->getBlueHorizon();
+ m_atmosphericsVars.haze_density = psky->getHazeDensity();
+ m_atmosphericsVars.haze_horizon = psky->getHazeHorizon();
+ m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier();
+ m_atmosphericsVars.distance_multiplier = psky->getDistanceMultiplier();
+ m_atmosphericsVars.max_y = psky->getMaxY();
+ m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm();
+ m_atmosphericsVars.sunlight = psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor();
+ m_atmosphericsVars.ambient = psky->getAmbientColor();
+ m_atmosphericsVars.glow = psky->getGlow();
+ m_atmosphericsVars.cloud_shadow = psky->getCloudShadow();
+ m_atmosphericsVars.dome_radius = psky->getDomeRadius();
+ m_atmosphericsVars.dome_offset = psky->getDomeOffset();
+ m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y);
+ m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(m_atmosphericsVars.max_y);
+ m_atmosphericsVars.gamma = psky->getGamma();
+
+ mSun.setColor(psky->getSunDiffuse());
+ mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
+
+ mSun.renewDirection();
+ mSun.renewColor();
+ mMoon.renewDirection();
+ mMoon.renewColor();
}
void LLVOSky::initCubeMap()
{
std::vector<LLPointer<LLImageRaw> > images;
- for (S32 side = 0; side < 6; side++)
+ for (S32 side = 0; side < NUM_CUBEMAP_FACES; side++)
{
images.push_back(mShinyTex[side].getImageRaw());
}
- if (mCubeMap)
+
+ if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
{
- mCubeMap->init(images);
+ mCubeMap = new LLCubeMap(false);
}
- else if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+
+ if (mCubeMap)
{
- mCubeMap = new LLCubeMap();
mCubeMap->init(images);
}
+
gGL.getTexUnit(0)->disable();
}
@@ -457,7 +566,7 @@ void LLVOSky::initCubeMap()
void LLVOSky::cleanupGL()
{
S32 i;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < NUM_CUBEMAP_FACES; i++)
{
mSkyTex[i].cleanupGL();
}
@@ -470,37 +579,27 @@ void LLVOSky::cleanupGL()
void LLVOSky::restoreGL()
{
S32 i;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < NUM_CUBEMAP_FACES; i++)
{
mSkyTex[i].restoreGL();
}
- mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
- mBloomTexturep->setNoDelete() ;
- mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- calcAtmospherics();
-
- if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap
- && LLCubeMap::sUseCubeMaps)
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
+ if (psky)
{
- LLCubeMap* cube_map = getCubeMap();
+ setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId());
+ setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId());
+ }
- std::vector<LLPointer<LLImageRaw> > images;
- for (S32 side = 0; side < 6; side++)
- {
- images.push_back(mShinyTex[side].getImageRaw());
- }
+ updateDirections();
- if(cube_map)
+ if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
{
- cube_map->init(images);
- mForceUpdate = TRUE;
+ initCubeMap();
}
- }
+
+ forceSkyUpdate();
if (mDrawable)
{
@@ -541,8 +640,10 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
}
}
-void LLVOSky::createSkyTexture(const S32 side, const S32 tile)
+void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile)
{
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+
S32 tile_x = tile % NUM_TILES_X;
S32 tile_y = tile / NUM_TILES_X;
@@ -554,704 +655,347 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile)
{
for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
{
- mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y);
- mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y);
+ mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mSkyTex[side].getDir(x, y), false), x, y);
+ mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(psky, vars, mShinyTex[side].getDir(x, y), true), x, y);
}
}
}
-static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
-{
- return LLColor3(left.mV[0]/right.mV[0],
- left.mV[1]/right.mV[1],
- left.mV[2]/right.mV[2]);
-}
-
-
-static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
-{
- return LLColor3(left.mV[0]*right.mV[0],
- left.mV[1]*right.mV[1],
- left.mV[2]*right.mV[2]);
-}
-
-
-static inline LLColor3 componentExp(LLColor3 const &v)
+void LLVOSky::updateDirections(void)
{
- return LLColor3(exp(v.mV[0]),
- exp(v.mV[1]),
- exp(v.mV[2]));
-}
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
-{
- return LLColor3(pow(v.mV[0], exponent),
- pow(v.mV[1], exponent),
- pow(v.mV[2], exponent));
+ mSun.setDirection(psky->getSunDirection());
+ mMoon.setDirection(psky->getMoonDirection());
+ mSun.setRotation(psky->getSunRotation());
+ mMoon.setRotation(psky->getMoonRotation());
+ mSun.renewDirection();
+ mMoon.renewDirection();
}
-static inline LLColor3 componentSaturate(LLColor3 const &v)
+void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
{
- return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
- std::max(std::min(v.mV[1], 1.f), 0.f),
- std::max(std::min(v.mV[2], 1.f), 0.f));
}
-
-static inline LLColor3 componentSqrt(LLColor3 const &v)
+void LLVOSky::forceSkyUpdate()
{
- return LLColor3(sqrt(v.mV[0]),
- sqrt(v.mV[1]),
- sqrt(v.mV[2]));
-}
+ mForceUpdate = TRUE;
-static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
-{
- left.mV[0] *= right.mV[0];
- left.mV[1] *= right.mV[1];
- left.mV[2] *= right.mV[2];
-}
+ memset(&m_lastAtmosphericsVars, 0x00, sizeof(AtmosphericsVars));
-static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
-{
- return (left + ((right - left) * amount));
+ mCubeMapUpdateStage = -1;
}
-static inline LLColor3 smear(F32 val)
+bool LLVOSky::updateSky()
{
- return LLColor3(val, val, val);
-}
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-void LLVOSky::initAtmospherics(void)
-{
- bool error;
-
- // uniform parameters for convenience
- dome_radius = LLWLParamManager::getInstance()->getDomeRadius();
- dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset();
- sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error));
- ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error));
- //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error);
- gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error);
- blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error));
- blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error));
- haze_density = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_density", error);
- haze_horizon = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_horizon", error);
- density_multiplier = LLWLParamManager::getInstance()->mCurParams.getFloat("density_multiplier", error);
- max_y = LLWLParamManager::getInstance()->mCurParams.getFloat("max_y", error);
- glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error));
- cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", error);
- cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error));
- cloud_scale = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_scale", error);
- cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error));
- cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error));
-
- // light norm is different. We need the sun's direction, not the light direction
- // which could be from the moon. And we need to clamp it
- // just like for the gpu
- LLVector3 sunDir = gSky.getSunDirection();
-
- // CFR_TO_OGL
- lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0);
- unclamped_lightnorm = lightnorm;
- if(lightnorm.mV[1] < -0.1f)
+ if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
{
- lightnorm.mV[1] = -0.1f;
+ return TRUE;
}
-
-}
-LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny)
-{
- F32 saturation = 0.3f;
- if (dir.mV[VZ] < -0.02f)
+ if (mDead)
{
- LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f);
- if (isShiny)
- {
- LLColor3 desat_fog = LLColor3(mFogColor);
- F32 brightness = desat_fog.brightness();
- // So that shiny somewhat shows up at night.
- if (brightness < 0.15f)
- {
- brightness = 0.15f;
- desat_fog = smear(0.15f);
- }
- LLColor3 greyscale = smear(brightness);
- desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation);
- if (!gPipeline.canUseWindLightShaders())
- {
- col = LLColor4(desat_fog, 0.f);
- }
- else
- {
- col = LLColor4(desat_fog * 0.5f, 0.f);
- }
- }
- float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]);
- x *= x;
- col.mV[0] *= x*x;
- col.mV[1] *= powf(x, 2.5f);
- col.mV[2] *= x*x*x;
- return col;
+ // It's dead. Don't update it.
+ return TRUE;
}
- // undo OGL_TO_CFR_ROTATION and negate vertical direction.
- LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
-
- LLColor3 vary_HazeColor(0,0,0);
- LLColor3 vary_CloudColorSun(0,0,0);
- LLColor3 vary_CloudColorAmbient(0,0,0);
- F32 vary_CloudDensity(0);
- LLVector2 vary_HorizontalProjection[2];
- vary_HorizontalProjection[0] = LLVector2(0,0);
- vary_HorizontalProjection[1] = LLVector2(0,0);
-
- calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
- vary_CloudDensity, vary_HorizontalProjection);
-
- LLColor3 sky_color = calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
- vary_CloudDensity, vary_HorizontalProjection);
- if (isShiny)
+ if (gGLManager.mIsDisabled)
{
- F32 brightness = sky_color.brightness();
- LLColor3 greyscale = smear(brightness);
- sky_color = sky_color * saturation + greyscale * (1.0f - saturation);
- sky_color *= (0.5f + 0.5f * brightness);
- }
- return LLColor4(sky_color, 0.0f);
-}
-
-// turn on floating point precision
-// in vs2003 for this function. Otherwise
-// sky is aliased looking 7:10 - 8:50
-#if LL_MSVC && __MSVC_VER__ < 8
-#pragma optimize("p", on)
-#endif
-
-void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
- LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
- LLVector2 vary_HorizontalProjection[2])
-{
- // project the direction ray onto the sky dome.
- F32 phi = acos(Pn[1]);
- F32 sinA = sin(F_PI - phi);
- if (fabsf(sinA) < 0.01f)
- { //avoid division by zero
- sinA = 0.01f;
+ return TRUE;
}
- F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA;
+ static S32 next_frame = 0;
+ const S32 total_no_tiles = NUM_CUBEMAP_FACES * NUM_TILES;
+ const S32 cycle_frame_no = total_no_tiles + 1;
+
+ mNeedUpdate = mForceUpdate;
- Pn *= Plen;
+ ++next_frame;
+ next_frame = next_frame % cycle_frame_no;
- vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]);
- vary_HorizontalProjection[0] /= - 2.f * Plen;
+ mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
+ LLHeavenBody::setInterpVal( mInterpVal );
+ updateDirections();
- // Set altitude
- if (Pn[1] > 0.f)
- {
- Pn *= (max_y / Pn[1]);
- }
- else
+ if (!mCubeMap)
{
- Pn *= (-32000.f / Pn[1]);
+ mCubeMapUpdateStage = NUM_CUBEMAP_FACES;
+ mForceUpdate = FALSE;
+ return TRUE;
}
+
+ if (mCubeMapUpdateStage < 0)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_VOSKY_CALC);
+ calc();
- Plen = Pn.length();
- Pn /= Plen;
-
- // Initialize temp variables
- LLColor3 sunlight = sunlight_color;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- LLColor3 light_atten =
- (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- LLColor3 temp2(0.f, 0.f, 0.f);
- LLColor3 temp1 = blue_density + smear(haze_density);
- LLColor3 blue_weight = componentDiv(blue_density, temp1);
- LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
-
- // Compute sunlight from P & lightnorm (for long rays like sky)
- temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
-
- temp2.mV[1] = 1.f / temp2.mV[1];
- componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
-
- // Distance
- temp2.mV[2] = Plen * density_multiplier;
-
- // Transparency (-> temp1)
- temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
-
-
- // Compute haze glow
- temp2.mV[0] = Pn * LLVector3(lightnorm);
-
- temp2.mV[0] = 1.f - temp2.mV[0];
- // temp2.x is 0 at the sun and increases away from sun
- temp2.mV[0] = llmax(temp2.mV[0], .001f);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.mV[0] *= glow.mV[0];
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- temp2.mV[0] += .25f;
-
-
- // Haze color above cloud
- vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient)
- + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient)
- );
-
- // Increase ambient when there are more clouds
- LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= (1.f - cloud_shadow);
-
- // Haze color below cloud
- LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient)
- + componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)
- );
-
- // Final atmosphere additive
- componentMultBy(vary_HazeColor, LLColor3::white - temp1);
-
- sunlight = sunlight_color;
- temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f);
- temp2.mV[1] = 1.f / temp2.mV[1];
- componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
+ bool same_atmospherics = approximatelyEqual(m_lastAtmosphericsVars, m_atmosphericsVars, UPDATE_MIN_DELTA_THRESHOLD);
- // Attenuate cloud color by atmosphere
- temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds
+ mNeedUpdate = mNeedUpdate || !same_atmospherics;
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- vary_HazeColor +=
- componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1));
-
- if (Pn[1] < 0.f)
- {
- // Eric's original:
- // LLColor3 dark_brown(0.143f, 0.129f, 0.114f);
- LLColor3 dark_brown(0.082f, 0.076f, 0.066f);
- LLColor3 brown(0.430f, 0.386f, 0.322f);
- LLColor3 sky_lighting = sunlight + ambient;
- F32 haze_brightness = vary_HazeColor.brightness();
-
- if (Pn[1] < -0.05f)
- {
- vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness;
- }
-
- if (Pn[1] > -0.1f)
+ if (mNeedUpdate && (mForceUpdateThrottle.hasExpired() || mForceUpdate))
{
- vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f));
+ // start updating cube map sides
+ updateFog(LLViewerCamera::getInstance()->getFar());
+ mCubeMapUpdateStage = 0;
+ mForceUpdate = FALSE;
}
}
-}
+ else if (mCubeMapUpdateStage == NUM_CUBEMAP_FACES)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED);
+ LLSkyTex::stepCurrent();
+
+ bool is_alm_wl_sky = gPipeline.canUseWindLightShaders();
+
+ int tex = mSkyTex[0].getWhich(TRUE);
+
+ for (int side = 0; side < NUM_CUBEMAP_FACES; side++)
+ {
+ LLImageRaw* raw1 = nullptr;
+ LLImageRaw* raw2 = nullptr;
+
+ if (!is_alm_wl_sky)
+ {
+ raw1 = mSkyTex[side].getImageRaw(TRUE);
+ raw2 = mSkyTex[side].getImageRaw(FALSE);
+ raw2->copy(raw1);
+ mSkyTex[side].createGLImage(tex);
+ }
+
+ raw1 = mShinyTex[side].getImageRaw(TRUE);
+ raw2 = mShinyTex[side].getImageRaw(FALSE);
+ raw2->copy(raw1);
+ mShinyTex[side].createGLImage(tex);
+ }
+ next_frame = 0;
+
+ // update the sky texture
+ if (!is_alm_wl_sky)
+ {
+ for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
+ {
+ mSkyTex[i].create();
+ }
+ }
+
+ for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
+ {
+ mShinyTex[i].create();
+ }
+
+ // update the environment map
+ initCubeMap();
+
+ m_lastAtmosphericsVars = m_atmosphericsVars;
+
+ mNeedUpdate = FALSE;
+ mForceUpdate = FALSE;
+
+ mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY);
+ gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+
+ if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ }
+ mCubeMapUpdateStage = -1;
+ }
+ // run 0 to 5 faces, each face in own frame
+ else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_VOSKY_CREATETEXTURES);
+ S32 side = mCubeMapUpdateStage;
+ // CPU hungry part, createSkyTexture() is math heavy
+ // Prior to EEP it was mostly per tile, but since EPP it is per face.
+ // This still can be optimized further
+ // (i.e. potentially can be made per tile again, can be moved to thread
+ // instead of executing per face, or may be can be moved to shaders)
+ for (S32 tile = 0; tile < NUM_TILES; tile++)
+ {
+ createSkyTexture(m_atmosphericsVars, side, tile);
+ }
+ mCubeMapUpdateStage++;
+ }
-#if LL_MSVC && __MSVC_VER__ < 8
-#pragma optimize("p", off)
-#endif
+ return TRUE;
+}
-LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
- LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
- LLVector2 vary_HorizontalProjection[2])
+void LLVOSky::updateTextures()
{
- LLColor3 res;
-
- LLColor3 color0 = vary_HazeColor;
-
- if (!gPipeline.canUseWindLightShaders())
+ if (mSunTexturep[0])
{
- LLColor3 color1 = color0 * 2.0f;
- color1 = smear(1.f) - componentSaturate(color1);
- componentPow(color1, gamma);
- res = smear(1.f) - color1;
- }
- else
- {
- res = color0;
+ mSunTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
-# ifndef LL_RELEASE_FOR_DOWNLOAD
-
- LLColor3 color2 = 2.f * color0;
-
- LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2);
- componentPow(color3, gamma);
- color3 = LLColor3(1.f, 1.f, 1.f) - color3;
-
- static enum {
- OUT_DEFAULT = 0,
- OUT_SKY_BLUE = 1,
- OUT_RED = 2,
- OUT_PN = 3,
- OUT_HAZE = 4,
- } debugOut = OUT_DEFAULT;
-
- switch(debugOut)
+ if (mSunTexturep[1])
{
- case OUT_DEFAULT:
- break;
- case OUT_SKY_BLUE:
- res = LLColor3(0.4f, 0.4f, 0.9f);
- break;
- case OUT_RED:
- res = LLColor3(1.f, 0.f, 0.f);
- break;
- case OUT_PN:
- res = LLColor3(Pn[0], Pn[1], Pn[2]);
- break;
- case OUT_HAZE:
- res = vary_HazeColor;
- break;
- }
-# endif // LL_RELEASE_FOR_DOWNLOAD
- return res;
+ mSunTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
-LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
+ if (mMoonTexturep[0])
{
- return componentMult(diffuse, sundiffuse) * 4.0f +
- componentMult(ambient, sundiffuse) * 2.0f + sunambient;
+ mMoonTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
-LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
+ if (mMoonTexturep[1])
{
- return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f;
+ mMoonTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
-
-void LLVOSky::calcAtmospherics(void)
-{
- initAtmospherics();
-
- LLColor3 vary_HazeColor;
- LLColor3 vary_SunlightColor;
- LLColor3 vary_AmbientColor;
+ if (mBloomTexturep[0])
{
- // Initialize temp variables
- LLColor3 sunlight = sunlight_color;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- LLColor3 light_atten =
- (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- LLColor3 temp2(0.f, 0.f, 0.f);
- LLColor3 temp1 = blue_density + smear(haze_density);
- LLColor3 blue_weight = componentDiv(blue_density, temp1);
- LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
-
- // Compute sunlight from P & lightnorm (for long rays like sky)
- /// USE only lightnorm.
- // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
-
- // and vary_sunlight will work properly with moon light
- F32 lighty = unclamped_lightnorm[1];
- if(lighty < LLSky::NIGHTTIME_ELEVATION_COS)
- {
- lighty = -lighty;
+ mBloomTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
- temp2.mV[1] = llmax(0.f, lighty);
- if(temp2.mV[1] > 0.f)
+ if (mBloomTexturep[1])
{
- temp2.mV[1] = 1.f / temp2.mV[1];
+ mBloomTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA );
}
- componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
-
- // Distance
- temp2.mV[2] = density_multiplier;
-
- // Transparency (-> temp1)
- temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
-
- // vary_AtmosAttenuation = temp1;
-
- //increase ambient when there are more clouds
- LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
-
- //haze color
- vary_HazeColor =
- (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)
- + componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient)
- );
-
- //brightness of surface both sunlight and ambient
- vary_SunlightColor = componentMult(sunlight, temp1) * 1.f;
- vary_SunlightColor.clamp();
- vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
- vary_SunlightColor = componentPow(vary_SunlightColor, gamma);
- vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
- vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5;
- vary_AmbientColor.clamp();
- vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
- vary_AmbientColor = componentPow(vary_AmbientColor, gamma);
- vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
-
- componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1);
-
}
- mSun.setColor(vary_SunlightColor);
- mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
+LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
+{
+ pipeline->allocDrawable(this);
+ mDrawable->setLit(FALSE);
- mSun.renewDirection();
- mSun.renewColor();
- mMoon.renewDirection();
- mMoon.renewColor();
+ LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
+ poolp->setSkyTex(mSkyTex);
+ mDrawable->setRenderType(LLPipeline::RENDER_TYPE_SKY);
- float dp = getToSunLast() * LLVector3(0,0,1.f);
- if (dp < 0)
+ for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
{
- dp = 0;
+ mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
}
- // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
- // between sunlight and point lights in windlight to normalize point lights.
- F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
- LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp);
+ mFace[FACE_SUN] = mDrawable->addFace(poolp, nullptr);
+ mFace[FACE_MOON] = mDrawable->addFace(poolp, nullptr);
+ mFace[FACE_BLOOM] = mDrawable->addFace(poolp, nullptr);
- mSunDiffuse = vary_SunlightColor;
- mSunAmbient = vary_AmbientColor;
- mMoonDiffuse = vary_SunlightColor;
- mMoonAmbient = vary_AmbientColor;
+ mFace[FACE_SUN]->setMediaAllowed(false);
+ mFace[FACE_MOON]->setMediaAllowed(false);
+ mFace[FACE_BLOOM]->setMediaAllowed(false);
- mTotalAmbient = vary_AmbientColor;
- mTotalAmbient.setAlpha(1);
-
- mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
- mFadeColor.setAlpha(0);
+ return mDrawable;
}
-void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
+void LLVOSky::setSunScale(F32 sun_scale)
{
+ mSunScale = sun_scale;
}
-BOOL LLVOSky::updateSky()
+void LLVOSky::setMoonScale(F32 moon_scale)
{
- if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
- {
- return TRUE;
+ mMoonScale = moon_scale;
}
- if (mDead)
+void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next)
{
- // It's dead. Don't update it.
- return TRUE;
- }
- if (gGLManager.mIsDisabled)
- {
- return TRUE;
- }
+ // We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case...
+ mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- static S32 next_frame = 0;
- const S32 total_no_tiles = 6 * NUM_TILES;
- const S32 cycle_frame_no = total_no_tiles + 1;
+ bool can_use_wl = gPipeline.canUseWindLightShaders();
- if (mUpdateTimer.getElapsedTimeF32() > 0.001f)
+ if (mFace[FACE_SUN])
{
- mUpdateTimer.reset();
- const S32 frame = next_frame;
-
- ++next_frame;
- next_frame = next_frame % cycle_frame_no;
+ if (mSunTexturep[0])
+ {
+ mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
- mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
- // sInterpVal = (F32)next_frame / cycle_frame_no;
- LLSkyTex::setInterpVal( mInterpVal );
- LLHeavenBody::setInterpVal( mInterpVal );
- calcAtmospherics();
+ LLViewerTexture* current_tex0 = mFace[FACE_SUN]->getTexture(LLRender::DIFFUSE_MAP);
+ LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
- if (mForceUpdate || total_no_tiles == frame)
- {
- LLSkyTex::stepCurrent();
-
- const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f);
- const static F32 COLOR_CHANGE_THRESHOLD = 0.01f;
-
- LLVector3 direction = mSun.getDirection();
- direction.normalize();
- const F32 dot_lighting = direction * mLastLightingDirection;
-
- LLColor3 delta_color;
- delta_color.setVec(mLastTotalAmbient.mV[0] - mTotalAmbient.mV[0],
- mLastTotalAmbient.mV[1] - mTotalAmbient.mV[1],
- mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]);
-
- if ( mForceUpdate
- || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD)
- || (delta_color.length() > COLOR_CHANGE_THRESHOLD)
- || !mInitialized)
- && !direction.isExactlyZero()))
+ if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture())
{
- mLastLightingDirection = direction;
- mLastTotalAmbient = mTotalAmbient;
- mInitialized = TRUE;
+ static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]);
+ }
- if (mCubeMap)
+ if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture())
{
- if (mForceUpdate)
- {
- updateFog(LLViewerCamera::getInstance()->getFar());
- for (int side = 0; side < 6; side++)
- {
- for (int tile = 0; tile < NUM_TILES; tile++)
- {
- createSkyTexture(side, tile);
- }
+ static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]);
}
- calcAtmospherics();
+ mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
- for (int side = 0; side < 6; side++)
+ if (can_use_wl)
+ {
+ if (mSunTexturep[1])
{
- LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE);
- LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE);
- raw2->copy(raw1);
- mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE));
-
- raw1 = mShinyTex[side].getImageRaw(TRUE);
- raw2 = mShinyTex[side].getImageRaw(FALSE);
- raw2->copy(raw1);
- mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE));
+ mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
- next_frame = 0;
+ mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
}
}
}
- /// *TODO really, sky texture and env map should be shared on a single texture
- /// I'll let Brad take this at some point
-
- // update the sky texture
- for (S32 i = 0; i < 6; ++i)
+void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next)
{
- mSkyTex[i].create(1.0f);
- mShinyTex[i].create(1.0f);
- }
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- // update the environment map
- if (mCubeMap)
- {
- std::vector<LLPointer<LLImageRaw> > images;
- images.reserve(6);
- for (S32 side = 0; side < 6; side++)
- {
- images.push_back(mShinyTex[side].getImageRaw(TRUE));
- }
- mCubeMap->init(images);
- gGL.getTexUnit(0)->disable();
- }
+ bool can_use_wl = gPipeline.canUseWindLightShaders();
- gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- // *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad.
- //gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ mMoonTexturep[0] = moon_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mMoonTexturep[1] = moon_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- mForceUpdate = FALSE;
- }
- else
+ if (mFace[FACE_MOON])
+ {
+ if (mMoonTexturep[0])
{
- const S32 side = frame / NUM_TILES;
- const S32 tile = frame % NUM_TILES;
- createSkyTexture(side, tile);
- }
+ mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
+ mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
- if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())
+ if (mMoonTexturep[1] && can_use_wl)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
}
- return TRUE;
-}
-
-void LLVOSky::updateTextures()
-{
- if (mSunTexturep)
- {
- mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
- mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
- mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
}
}
-LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
+void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next)
{
- pipeline->allocDrawable(this);
- mDrawable->setLit(FALSE);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
- poolp->setSkyTex(mSkyTex);
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_SKY);
+ mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
- for (S32 i = 0; i < 6; ++i)
+ if (mCloudNoiseTexturep[0])
{
- mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
+ mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
}
- mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep);
- mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep);
- mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);
-
- return mDrawable;
+ if (mCloudNoiseTexturep[1])
+ {
+ mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP);
+ }
}
-//by bao
-//fake vertex buffer updating
-//to guarantee at least updating one VBO buffer every frame
-//to walk around the bug caused by ATI card --> DEV-3855
-//
-void LLVOSky::createDummyVertexBuffer()
+void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next)
{
- if(!mFace[FACE_DUMMY])
- {
- LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
- mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL);
- }
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- if(!mFace[FACE_DUMMY]->getVertexBuffer())
- {
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
- buff->allocateBuffer(1, 1, TRUE);
- mFace[FACE_DUMMY]->setVertexBuffer(buff);
- }
-}
+ LLUUID bloom_tex = bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture;
+ LLUUID bloom_tex_next = bloom_texture_next.isNull() ? (bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture) : bloom_texture_next;
-static LLTrace::BlockTimerStatHandle FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update");
+ mBloomTexturep[0] = bloom_tex.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
-void LLVOSky::updateDummyVertexBuffer()
+ if (mBloomTexturep[0])
{
- if(!LLVertexBuffer::sEnableVBOs)
- return ;
+ mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
- if(mHeavenlyBodyUpdated)
+ if (mBloomTexturep[1])
{
- mHeavenlyBodyUpdated = FALSE ;
- return ;
+ mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
}
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FAKE_VBO_UPDATE) ;
-
- if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer())
- createDummyVertexBuffer() ;
-
- LLStrider<LLVector3> vertices ;
- mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0);
- *vertices = mCameraPosAgent ;
- mFace[FACE_DUMMY]->getVertexBuffer()->flush();
-}
-//----------------------------------
-//end of fake vertex buffer updating
-//----------------------------------
static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");
BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
@@ -1260,13 +1004,14 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
if (mFace[FACE_REFLECTION] == NULL)
{
LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
- if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() != 0)
+ if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() != 0)
{
mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);
}
}
mCameraPosAgent = drawable->getPositionAgent();
+
mEarthCenter.mV[0] = mCameraPosAgent.mV[0];
mEarthCenter.mV[1] = mCameraPosAgent.mV[1];
@@ -1286,7 +1031,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
U16 index_offset;
LLFace *face;
- for (S32 side = 0; side < 6; ++side)
+ for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
{
face = mFace[FACE_SIDE0 + side];
@@ -1341,63 +1086,39 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
right.normalize();
up.normalize();
- const static F32 elevation_factor = 0.0f/sResolution;
- const F32 cos_max_angle = cosHorizon(elevation_factor);
- mSun.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_SUN, TRUE, mSun, cos_max_angle, up, right));
- mMoon.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_MOON, FALSE, mMoon, cos_max_angle, up, right));
+ bool draw_sun = updateHeavenlyBodyGeometry(drawable, mSunScale, FACE_SUN, mSun, up, right);
+ bool draw_moon = updateHeavenlyBodyGeometry(drawable, mMoonScale, FACE_MOON, mMoon, up, right);
+
+ draw_sun &= LLEnvironment::getInstance()->getIsSunUp();
+ draw_moon &= LLEnvironment::getInstance()->getIsMoonUp();
+
+ mSun.setDraw(draw_sun);
+ mMoon.setDraw(draw_moon);
const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.01f;
// LLWorld::getInstance()->getWaterHeight() + 0.01f;
const F32 camera_height = mCameraPosAgent.mV[2];
const F32 height_above_water = camera_height - water_height;
- BOOL sun_flag = FALSE;
-
+ bool sun_flag = FALSE;
if (mSun.isVisible())
{
- if (mMoon.isVisible())
- {
- sun_flag = look_at * mSun.getDirection() > 0;
+ sun_flag = !mMoon.isVisible() || ((look_at * mSun.getDirection()) > 0);
}
- else
- {
- sun_flag = TRUE;
- }
- }
-
- if (height_above_water > 0)
- {
- BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
- if (sun_flag)
- {
- setDrawRefl(0);
+ bool above_water = (height_above_water > 0);
+ bool render_ref = above_water && gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() == 0;
+ setDrawRefl(above_water ? (sun_flag ? 0 : 1) : -1);
if (render_ref)
{
updateReflectionGeometry(drawable, height_above_water, mSun);
}
- }
- else
- {
- setDrawRefl(1);
- if (render_ref)
- {
- updateReflectionGeometry(drawable, height_above_water, mMoon);
- }
- }
- }
- else
- {
- setDrawRefl(-1);
- }
LLPipeline::sCompiles++;
return TRUE;
}
-BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun,
- LLHeavenBody& hb, const F32 cos_max_angle,
- const LLVector3 &up, const LLVector3 &right)
+bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const S32 f, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right)
{
mHeavenlyBodyUpdated = TRUE ;
@@ -1408,52 +1129,39 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
S32 index_offset;
LLFace *facep;
- LLVector3 to_dir = hb.getDirection();
- if (!is_sun)
+ LLQuaternion rot = hb.getRotation();
+ LLVector3 to_dir = LLVector3::x_axis * rot;
+
+ LLVector3 hb_right = to_dir % LLVector3::z_axis;
+ LLVector3 hb_up = hb_right % to_dir;
+
+ // at zenith so math below fails spectacularly
+ if ((to_dir * LLVector3::z_axis) > 0.99f)
{
- to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f);
+ hb_right = LLVector3::y_axis_neg * rot;
+ hb_up = LLVector3::z_axis * rot;
}
- LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
+ LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
- LLVector3 hb_right = to_dir % LLVector3::z_axis;
- LLVector3 hb_up = hb_right % to_dir;
hb_right.normalize();
hb_up.normalize();
- //const static F32 cos_max_turn = sqrt(3.f) / 2; // 30 degrees
- //const F32 cos_turn_right = 1. / (llmax(cos_max_turn, hb_right * right));
- //const F32 cos_turn_up = 1. / llmax(cos_max_turn, hb_up * up);
-
const F32 enlargm_factor = ( 1 - to_dir.mV[2] );
F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;
F32 vert_enlargement = 1 + enlargm_factor * 0.2f;
- // Parameters for the water reflection
- hb.setU(HEAVENLY_BODY_FACTOR * horiz_enlargement * hb.getDiskRadius() * hb_right);
- hb.setV(HEAVENLY_BODY_FACTOR * vert_enlargement * hb.getDiskRadius() * hb_up);
- // End of parameters for the water reflection
-
- const LLVector3 scaled_right = HEAVENLY_BODY_DIST * hb.getU();
- const LLVector3 scaled_up = HEAVENLY_BODY_DIST * hb.getV();
+ const LLVector3 scaled_right = horiz_enlargement * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_right;
+ const LLVector3 scaled_up = vert_enlargement * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_up;
- //const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_right;//right;
- //const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_up;//up;
LLVector3 v_clipped[4];
- hb.corner(0) = draw_pos - scaled_right + scaled_up;
- hb.corner(1) = draw_pos - scaled_right - scaled_up;
- hb.corner(2) = draw_pos + scaled_right + scaled_up;
- hb.corner(3) = draw_pos + scaled_right - scaled_up;
+ v_clipped[0] = draw_pos - scaled_right + scaled_up;
+ v_clipped[1] = draw_pos - scaled_right - scaled_up;
+ v_clipped[2] = draw_pos + scaled_right + scaled_up;
+ v_clipped[3] = draw_pos + scaled_right - scaled_up;
-
- F32 t_left, t_right;
- if (!clip_quad_to_horizon(t_left, t_right, v_clipped, hb.corners(), cos_max_angle))
- {
- hb.setVisible(FALSE);
- return FALSE;
- }
hb.setVisible(TRUE);
facep = mFace[f];
@@ -1503,164 +1211,9 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons
facep->getVertexBuffer()->flush();
- if (is_sun)
- {
- if ((t_left > 0) && (t_right > 0))
- {
- F32 t = (t_left + t_right) * 0.5f;
- mSun.setHorizonVisibility(0.5f * (1 + cos(t * F_PI)));
- }
- else
- {
- mSun.setHorizonVisibility();
- }
- updateSunHaloGeometry(drawable);
- }
-
- return TRUE;
-}
-
-
-
-
-// Clips quads with top and bottom sides parallel to horizon.
-
-BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4],
- const LLVector3 v_corner[4], const F32 cos_max_angle)
-{
- t_left = clip_side_to_horizon(v_corner[1], v_corner[0], cos_max_angle);
- t_right = clip_side_to_horizon(v_corner[3], v_corner[2], cos_max_angle);
-
- if ((t_left >= 1) || (t_right >= 1))
- {
- return FALSE;
- }
-
- //const BOOL left_clip = (t_left > 0);
- //const BOOL right_clip = (t_right > 0);
-
- //if (!left_clip && !right_clip)
- {
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- v_clipped[vtx] = v_corner[vtx];
- }
- }
-/* else
- {
- v_clipped[0] = v_corner[0];
- v_clipped[1] = left_clip ? ((1 - t_left) * v_corner[1] + t_left * v_corner[0])
- : v_corner[1];
- v_clipped[2] = v_corner[2];
- v_clipped[3] = right_clip ? ((1 - t_right) * v_corner[3] + t_right * v_corner[2])
- : v_corner[3];
- }*/
-
return TRUE;
}
-
-F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos_max_angle)
-{
- const LLVector3 V = V1 - V0;
- const F32 k2 = 1.f/(cos_max_angle * cos_max_angle) - 1;
- const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] - k2 * V.mV[2] * V.mV[2];
- const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] - k2 * V0.mV[2] * V.mV[2];
- const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] - k2 * V0.mV[2] * V0.mV[2];
-
- if (fabs(A) < 1e-7)
- {
- return -0.1f; // v0 is cone origin and v1 is on the surface of the cone.
- }
-
- const F32 det = sqrt(B*B - A*C);
- const F32 t1 = (-B - det) / A;
- const F32 t2 = (-B + det) / A;
- const F32 z1 = V0.mV[2] + t1 * V.mV[2];
- const F32 z2 = V0.mV[2] + t2 * V.mV[2];
- if (z1 * cos_max_angle < 0)
- {
- return t2;
- }
- else if (z2 * cos_max_angle < 0)
- {
- return t1;
- }
- else if ((t1 < 0) || (t1 > 1))
- {
- return t2;
- }
- else
- {
- return t1;
- }
-}
-
-
-void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable )
-{
-#if 0
- const LLVector3* v_corner = mSun.corners();
-
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texCoordsp;
- LLStrider<U16> indicesp;
- S32 index_offset;
- LLFace *face;
-
- const LLVector3 right = 2 * (v_corner[2] - v_corner[0]);
- LLVector3 up = 2 * (v_corner[2] - v_corner[3]);
- up.normalize();
- F32 size = right.length();
- up = size * up;
- const LLVector3 draw_pos = 0.25 * (v_corner[0] + v_corner[1] + v_corner[2] + v_corner[3]);
-
- LLVector3 v_glow_corner[4];
-
- v_glow_corner[0] = draw_pos - right + up;
- v_glow_corner[1] = draw_pos - right - up;
- v_glow_corner[2] = draw_pos + right + up;
- v_glow_corner[3] = draw_pos + right - up;
-
- face = mFace[FACE_BLOOM];
-
- if (face->mVertexBuffer.isNull())
- {
- face->setSize(4, 6);
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
- face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- face->mVertexBuffer->allocateBuffer(4, 6, TRUE);
- }
-
- index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
- if (-1 == index_offset)
- {
- return;
- }
-
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- *(verticesp++) = v_glow_corner[vtx] + mCameraPosAgent;
- }
-
- *(texCoordsp++) = TEX01;
- *(texCoordsp++) = TEX00;
- *(texCoordsp++) = TEX11;
- *(texCoordsp++) = TEX10;
-
- *indicesp++ = index_offset + 0;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
-
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
-#endif
-}
-
-
F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top, F32 sin_dir_from_top, F32 diff_angl_dir)
{
LLVector3 P = p;
@@ -1722,9 +1275,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
LLVector3 look_at_right = look_at % LLVector3::z_axis;
look_at_right.normalize();
- const static F32 cos_horizon_angle = cosHorizon(0.0f/sResolution);
- //const static F32 horizon_angle = acos(cos_horizon_angle);
-
const F32 enlargm_factor = ( 1 - to_dir.mV[2] );
F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;
F32 vert_enlargement = 1 + enlargm_factor * 0.2f;
@@ -1739,22 +1289,10 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - Right + Up;
v_corner[1] = stretch_corner[1] = hb_pos - Right - Up;
- F32 dt_hor, dt;
- dt_hor = clip_side_to_horizon(v_corner[1], v_corner[0], cos_horizon_angle);
-
LLVector2 TEX0t = TEX00;
LLVector2 TEX1t = TEX10;
LLVector3 lower_corner = v_corner[1];
- if ((dt_hor > 0) && (dt_hor < 1))
- {
- TEX0t = LLVector2(0, dt_hor);
- TEX1t = LLVector2(1, dt_hor);
- lower_corner = (1 - dt_hor) * v_corner[1] + dt_hor * v_corner[0];
- }
- else
- dt_hor = llmax(0.0f, llmin(1.0f, dt_hor));
-
top_hb.normalize();
const F32 cos_angle_of_view = fabs(top_hb.mV[VZ]);
const F32 extension = llmin (5.0f, 1.0f / cos_angle_of_view);
@@ -1766,9 +1304,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
stretch_corner[0] = lower_corner + extension * (stretch_corner[0] - lower_corner);
stretch_corner[1] = lower_corner + extension * (stretch_corner[1] - lower_corner);
- dt = dt_hor;
-
-
F32 cos_dir_from_top[2];
LLVector3 dir = stretch_corner[0];
@@ -1857,9 +1392,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
F32 dt_tex = dtReflection(P, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir);
- dt = dt_tex;
- TEX0tt = LLVector2(0, dt);
- TEX1tt = LLVector2(1, dt);
+ TEX0tt = LLVector2(0, dt_tex);
+ TEX1tt = LLVector2(1, dt_tex);
quads++;
}
else
@@ -1870,6 +1404,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
LLFace *face = mFace[FACE_REFLECTION];
+ if (face)
+ {
if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
{
face->setSize(quads * 4, quads * 6);
@@ -1906,7 +1442,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
const F32 attenuation = min_attenuation
+ cos_angle_of_view * (max_attenuation - min_attenuation);
- LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor;
+ LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor();
face->setFaceColor(hb_refl_col);
LLVector3 v_far[2];
@@ -1981,8 +1517,6 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
left *= raws_inv;
right *= raws_inv;
- F32 dt_raw = dt;
-
for (S32 raw = 0; raw < raws; ++raw)
{
F32 dt_v0 = raw * raws_inv;
@@ -1991,8 +1525,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
const LLVector3 BR = v_refl_corner[3] + (F32)raw * right;
const LLVector3 EL = BL + left;
const LLVector3 ER = BR + right;
- dt_v0 = dt_raw;
- dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir);
+ dt_v0 = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir);
for (S32 col = 0; col < cols; ++col)
{
F32 dt_h0 = col * cols_inv;
@@ -2022,256 +1555,65 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
face->getVertexBuffer()->flush();
}
-
-
-
+}
void LLVOSky::updateFog(const F32 distance)
{
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
+ LLEnvironment& environment = LLEnvironment::instance();
+ if (environment.getCurrentSky() != nullptr)
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogf(GL_FOG_DENSITY, 0);
- glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
- glFogf(GL_FOG_END, 1000000.f);
+ LLVector3 light_dir = LLVector3(environment.getClampedLightNorm());
+ m_legacyAtmospherics.updateFog(distance, light_dir);
}
- 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;
- // LLWorld::getInstance()->getWaterHeight();
- F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
-
- F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear();
- camera_height += near_clip_height;
-
- F32 fog_distance = 0.f;
- LLColor3 res_color[3];
-
- LLColor3 sky_fog_color = LLColor3::white;
- LLColor3 render_fog_color = LLColor3::white;
-
- LLVector3 tosun = getToSunLast();
- const F32 tosun_z = tosun.mV[VZ];
- tosun.mV[VZ] = 0.f;
- tosun.normalize();
- LLVector3 perp_tosun;
- perp_tosun.mV[VX] = -tosun.mV[VY];
- perp_tosun.mV[VY] = tosun.mV[VX];
- LLVector3 tosun_45 = tosun + perp_tosun;
- tosun_45.normalize();
-
- F32 delta = 0.06f;
- tosun.mV[VZ] = delta;
- perp_tosun.mV[VZ] = delta;
- tosun_45.mV[VZ] = delta;
- tosun.normalize();
- perp_tosun.normalize();
- tosun_45.normalize();
-
- // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun.
- initAtmospherics();
- res_color[0] = calcSkyColorInDir(tosun);
- res_color[1] = calcSkyColorInDir(perp_tosun);
- res_color[2] = calcSkyColorInDir(tosun_45);
-
- sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
-
- F32 full_off = -0.25f;
- F32 full_on = 0.00f;
- F32 on = (tosun_z - full_off) / (full_on - full_off);
- on = llclamp(on, 0.01f, 1.f);
- sky_fog_color *= 0.5f * on;
-
-
- // We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ???
- S32 i;
- for (i = 0; i < 3; i++)
+void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr)
{
- sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]);
- }
-
- color_gamma_correct(sky_fog_color);
+ mSun.setDirection(sun_dir_cfr);
+ mMoon.setDirection(moon_dir_cfr);
- render_fog_color = sky_fog_color;
-
- F32 fog_density = 0.f;
- fog_distance = mFogRatio * distance;
-
- if (camera_height > water_height)
+ // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
+ // on the upward facing faces of cubes.
{
- LLColor4 fog(render_fog_color);
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogfv(GL_FOG_COLOR, fog.mV);
- }
- mGLFogCol = fog;
+ // Same as dot product with the up direction + clamp.
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
+ sunDot *= sunDot;
- 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;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogi(GL_FOG_MODE, GL_EXP2);
- }
- }
- else
- {
- const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
- fog_density = (f_log)/fog_distance;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogi(GL_FOG_MODE, GL_EXP);
- }
- }
- }
- else
- {
- F32 depth = water_height - camera_height;
+ // Create normalized vector that has the sunDir pushed south about an hour and change.
+ LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
- // get the water param manager variables
- float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity();
- LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV);
-
- // adjust the color based on depth. We're doing linear approximations
- float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
- float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),
- gSavedSettings.getF32("WaterGLFogDepthFloor"));
-
- LLColor4 fogCol = water_fog_color * depth_modifier;
- fogCol.setAlpha(1);
-
- // set the gl fog color
- mGLFogCol = fogCol;
-
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
-
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
- glFogi(GL_FOG_MODE, GL_EXP2);
+ // Blend between normal sun dir and adjusted sun dir based on how close we are
+ // to having the sun overhead.
+ mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
+ mBumpSunDir.normalize();
}
+ updateDirections();
}
- mFogColor = sky_fog_color;
- mFogColor.setAlpha(1);
- LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
-
- if (!LLGLSLShader::sNoFixedFunction)
+void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr)
{
- LLGLSFog gls_fog;
- glFogf(GL_FOG_END, fog_distance*2.2f);
- glFogf(GL_FOG_DENSITY, fog_density);
- glHint(GL_FOG_HINT, GL_NICEST);
- }
- stop_glerror();
-}
-
-
-// Functions used a lot.
-F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
-{
- F32 mv = color_max(col);
- if (0 == mv)
- {
- return 0;
- }
-
- col *= 1.f / mv;
- color_pow(col, e);
- if (postmultiply)
- {
- col *= mv;
- }
- return mv;
-}
-
-// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis.
-// Range of output is 0.0f to 2pi //359.99999...f
-// Returns 0.0f when "v" = +/- z_axis.
-F32 azimuth(const LLVector3 &v)
-{
- F32 azimuth = 0.0f;
- if (v.mV[VX] == 0.0f)
- {
- if (v.mV[VY] > 0.0f)
- {
- azimuth = F_PI * 0.5f;
- }
- else if (v.mV[VY] < 0.0f)
- {
- azimuth = F_PI * 1.5f;// 270.f;
- }
- }
- else
- {
- azimuth = (F32) atan(v.mV[VY] / v.mV[VX]);
- if (v.mV[VX] < 0.0f)
- {
- azimuth += F_PI;
- }
- else if (v.mV[VY] < 0.0f)
- {
- azimuth += F_PI * 2;
- }
- }
- return azimuth;
-}
-
-void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
-{
- LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir;
- sun_direction.normalize();
- mSun.setDirection(sun_direction);
- mSun.renewDirection();
- mSun.setAngularVelocity(sun_ang_velocity);
- mMoon.setDirection(-mSun.getDirection());
- mMoon.renewDirection();
- mLastLightingDirection = mSun.getDirection();
-
- calcAtmospherics();
-
- if ( !mInitialized )
- {
- init();
- LLSkyTex::stepCurrent();
- }
-}
-
-void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
-{
- LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir;
- sun_direction.normalize();
+ mSun.setDirection(sun_dir_cfr);
// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
// on the upward facing faces of cubes.
- LLVector3 newDir = sun_direction;
-
+ {
// Same as dot product with the up direction + clamp.
- F32 sunDot = llmax(0.f, newDir.mV[2]);
+ F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]);
sunDot *= sunDot;
// Create normalized vector that has the sunDir pushed south about an hour and change.
- LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
+ LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
// Blend between normal sun dir and adjusted sun dir based on how close we are
// to having the sun overhead.
- mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot);
+ mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot);
mBumpSunDir.normalize();
+ }
+ updateDirections();
+}
- F32 dp = mLastLightingDirection * sun_direction;
- mSun.setDirection(sun_direction);
- mSun.setAngularVelocity(sun_ang_velocity);
- mMoon.setDirection(-sun_direction);
- calcAtmospherics();
- if (dp < 0.995f) { //the sun jumped a great deal, update immediately
- mForceUpdate = TRUE;
- }
+void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr)
+{
+ mMoon.setDirection(moon_dir_cfr);
+ updateDirections();
}
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 9cfb9773bd..39e42bbb24 100644
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -30,86 +30,22 @@
#include "stdtypes.h"
#include "v3color.h"
#include "v4coloru.h"
+#include "llquaternion.h"
#include "llviewertexture.h"
#include "llviewerobject.h"
#include "llframetimer.h"
+#include "v3colorutil.h"
+#include "llsettingssky.h"
+#include "lllegacyatmospherics.h"
-
-//////////////////////////////////
-//
-// Lots of constants
-//
-// Will clean these up at some point...
-//
-
-const F32 HORIZON_DIST = 1024.0f;
const F32 SKY_BOX_MULT = 16.0f;
-const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 10.f;
+const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 20.f;
const F32 HEAVENLY_BODY_FACTOR = 0.1f;
const F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
-const F32 EARTH_RADIUS = 6.4e6f; // exact radius = 6.37 x 10^6 m
-const F32 ATM_EXP_FALLOFF = 0.000126f;
-const F32 ATM_SEA_LEVEL_NDENS = 2.55e25f;
-// Somewhat arbitrary:
-const F32 ATM_HEIGHT = 100000.f;
-
-const F32 FIRST_STEP = 5000.f;
-const F32 INV_FIRST_STEP = 1.f/FIRST_STEP;
-const S32 NO_STEPS = 15;
-const F32 INV_NO_STEPS = 1.f/NO_STEPS;
-
-
-// constants used in calculation of scattering coeff of clear air
-const F32 sigma = 0.035f;
-const F32 fsigma = (6.f + 3.f * sigma) / (6.f-7.f*sigma);
-const F64 Ndens = 2.55e25;
-const F64 Ndens2 = Ndens*Ndens;
-
-// HACK: Allow server to change sun and moon IDs.
-// I can't figure out how to pass the appropriate
-// information into the LLVOSky constructor. JC
-extern LLUUID gSunTextureID;
-extern LLUUID gMoonTextureID;
-
-
-LL_FORCE_INLINE LLColor3 color_div(const LLColor3 &col1, const LLColor3 &col2)
-{
- return LLColor3(
- col1.mV[0] / col2.mV[0],
- col1.mV[1] / col2.mV[1],
- col1.mV[2] / col2.mV[2] );
-}
-
-LLColor3 color_norm(const LLColor3 &col);
-BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4],
- const LLVector3 v_corner[4], const F32 cos_max_angle);
-F32 clip_side_to_horizon(const LLVector3& v0, const LLVector3& v1, const F32 cos_max_angle);
-
-inline F32 color_intens ( const LLColor3 &col )
-{
- return col.mV[0] + col.mV[1] + col.mV[2];
-}
-
-inline F32 color_max(const LLColor3 &col)
-{
- return llmax(col.mV[0], col.mV[1], col.mV[2]);
-}
-
-inline F32 color_max(const LLColor4 &col)
-{
- return llmax(col.mV[0], col.mV[1], col.mV[2]);
-}
-
-
-inline F32 color_min(const LLColor3 &col)
-{
- return llmin(col.mV[0], col.mV[1], col.mV[2]);
-}
class LLFace;
class LLHaze;
-
class LLSkyTex
{
friend class LLVOSky;
@@ -121,33 +57,28 @@ private:
LLColor4 *mSkyData;
LLVector3 *mSkyDirs; // Cache of sky direction vectors
static S32 sCurrent;
- static F32 sInterpVal;
public:
- static F32 getInterpVal() { return sInterpVal; }
- static void setInterpVal(const F32 v) { sInterpVal = v; }
- static BOOL doInterpolate() { return sInterpVal > 0.001f; }
-
void bindTexture(BOOL curr = TRUE);
protected:
LLSkyTex();
- void init();
+ void init(bool isShiny);
void cleanupGL();
void restoreGL();
~LLSkyTex();
- static S32 getResolution() { return sResolution; }
- static S32 getCurrent() { return sCurrent; }
- static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; }
- static S32 getNext() { return ((sCurrent+1) & 1); }
- static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); }
+ static S32 getResolution();
+ static S32 getCurrent();
+ static S32 stepCurrent();
+ static S32 getNext();
+ static S32 getWhich(const BOOL curr);
void initEmpty(const S32 tex);
- void create(F32 brightness);
+ void create();
void setDir(const LLVector3 &dir, const S32 i, const S32 j)
{
@@ -183,8 +114,10 @@ protected:
return col;
}
- LLImageRaw* getImageRaw(BOOL curr=TRUE) { return mImageRaw[getWhich(curr)]; }
+ LLImageRaw* getImageRaw(BOOL curr=TRUE);
void createGLImage(BOOL curr=TRUE);
+
+ bool mIsShiny;
};
/// TODO Move into the stars draw pool (and rename them appropriately).
@@ -197,244 +130,70 @@ protected:
LLColor3 mColorCached;
F32 mIntensity;
LLVector3 mDirection; // direction of the local heavenly body
+ LLQuaternion mRotation;
LLVector3 mAngularVelocity; // velocity of the local heavenly body
F32 mDiskRadius;
- BOOL mDraw; // FALSE - do not draw.
+ bool mDraw; // FALSE - do not draw.
F32 mHorizonVisibility; // number [0, 1] due to how horizon
F32 mVisibility; // same but due to other objects being in throng.
- BOOL mVisible;
+ bool mVisible;
static F32 sInterpVal;
LLVector3 mQuadCorner[4];
- LLVector3 mU;
- LLVector3 mV;
LLVector3 mO;
public:
- LLHeavenBody(const F32 rad) :
- mDirectionCached(LLVector3(0,0,0)),
- mDirection(LLVector3(0,0,0)),
- mIntensity(0.f),
- mDiskRadius(rad), mDraw(FALSE),
- mHorizonVisibility(1.f), mVisibility(1.f),
- mVisible(FALSE)
- {
- mColor.setToBlack();
- mColorCached.setToBlack();
- }
+ LLHeavenBody(const F32 rad);
~LLHeavenBody() {}
- const LLVector3& getDirection() const { return mDirection; }
- void setDirection(const LLVector3 &direction) { mDirection = direction; }
- void setAngularVelocity(const LLVector3 &ang_vel) { mAngularVelocity = ang_vel; }
- const LLVector3& getAngularVelocity() const { return mAngularVelocity; }
-
- const LLVector3& getDirectionCached() const { return mDirectionCached; }
- void renewDirection() { mDirectionCached = mDirection; }
-
- const LLColor3& getColorCached() const { return mColorCached; }
- void setColorCached(const LLColor3& c) { mColorCached = c; }
- const LLColor3& getColor() const { return mColor; }
- void setColor(const LLColor3& c) { mColor = c; }
-
- void renewColor() { mColorCached = mColor; }
-
- static F32 interpVal() { return sInterpVal; }
- static void setInterpVal(const F32 v) { sInterpVal = v; }
-
- LLColor3 getInterpColor() const
- {
- return sInterpVal * mColor + (1 - sInterpVal) * mColorCached;
- }
-
- const F32& getHorizonVisibility() const { return mHorizonVisibility; }
- void setHorizonVisibility(const F32 c = 1) { mHorizonVisibility = c; }
- const F32& getVisibility() const { return mVisibility; }
- void setVisibility(const F32 c = 1) { mVisibility = c; }
- F32 getHaloBrighness() const
- {
- return llmax(0.f, llmin(0.9f, mHorizonVisibility)) * mVisibility;
- }
- BOOL isVisible() const { return mVisible; }
- void setVisible(const BOOL v) { mVisible = v; }
-
- const F32& getIntensity() const { return mIntensity; }
- void setIntensity(const F32 c) { mIntensity = c; }
-
- void setDiskRadius(const F32 radius) { mDiskRadius = radius; }
- F32 getDiskRadius() const { return mDiskRadius; }
-
- void setDraw(const BOOL draw) { mDraw = draw; }
- BOOL getDraw() const { return mDraw; }
+ const LLQuaternion& getRotation() const;
+ void setRotation(const LLQuaternion& rot);
- const LLVector3& corner(const S32 n) const { return mQuadCorner[n]; }
- LLVector3& corner(const S32 n) { return mQuadCorner[n]; }
- const LLVector3* corners() const { return mQuadCorner; }
-
- const LLVector3& getU() const { return mU; }
- const LLVector3& getV() const { return mV; }
- void setU(const LLVector3& u) { mU = u; }
- void setV(const LLVector3& v) { mV = v; }
-};
+ const LLVector3& getDirection() const;
+ void setDirection(const LLVector3 &direction);
+ void setAngularVelocity(const LLVector3 &ang_vel);
+ const LLVector3& getAngularVelocity() const;
+ const LLVector3& getDirectionCached() const;
+ void renewDirection();
-LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length)
-{
- LLColor3 refr_ind;
- for (S32 i = 0; i < 3; ++i)
- {
- const F32 wl2 = wave_length.mV[i] * wave_length.mV[i] * 1e-6f;
- refr_ind.mV[i] = 6.43e3f + ( 2.95e6f / ( 146.0f - 1.f/wl2 ) ) + ( 2.55e4f / ( 41.0f - 1.f/wl2 ) );
- refr_ind.mV[i] *= 1.0e-8f;
- refr_ind.mV[i] += 1.f;
- }
- return refr_ind;
-}
-
-
-class LLHaze
-{
-public:
- LLHaze() : mG(0), mFalloff(1), mAbsCoef(0.f) {mSigSca.setToBlack();}
- LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) :
- mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f)
- {
- mAbsCoef = color_intens(mSigSca) / sAirScaIntense;
- }
-
- LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g),
- mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo)
- {
- mAbsCoef = 0.01f * sca / sAirScaAvg;
- }
-
- F32 getG() const { return mG; }
+ const LLColor3& getColorCached() const;
+ void setColorCached(const LLColor3& c);
+ const LLColor3& getColor() const;
+ void setColor(const LLColor3& c);
- void setG(const F32 g)
- {
- mG = g;
- }
+ void renewColor();
- const LLColor3& getSigSca() const // sea level
- {
- return mSigSca;
- }
+ static F32 interpVal();
+ static void setInterpVal(const F32 v);
- void setSigSca(const LLColor3& s)
- {
- mSigSca = s;
- mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense;
- }
+ LLColor3 getInterpColor() const;
- void setSigSca(const F32 s0, const F32 s1, const F32 s2)
- {
- mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2);
- mAbsCoef = 0.01f * (s0 + s1 + s2) / 3;
- }
+ const F32& getVisibility() const;
+ void setVisibility(const F32 c = 1);
- F32 getFalloff() const
- {
- return mFalloff;
- }
+ bool isVisible() const;
+ void setVisible(const bool v);
- void setFalloff(const F32 fo)
- {
- mFalloff = fo;
- }
+ const F32& getIntensity() const;
+ void setIntensity(const F32 c);
- F32 getAbsCoef() const
- {
- return mAbsCoef;
- }
+ void setDiskRadius(const F32 radius);
+ F32 getDiskRadius() const;
- inline static F32 calcFalloff(const F32 h)
- {
- return (h <= 0) ? 1.0f : (F32)LL_FAST_EXP(-ATM_EXP_FALLOFF * h);
- }
+ void setDraw(const bool draw);
+ bool getDraw() const;
- inline LLColor3 calcSigSca(const F32 h) const
- {
- return calcFalloff(h * mFalloff) * mSigSca;
- }
-
- inline void calcSigSca(const F32 h, LLColor3 &result) const
- {
- result = mSigSca;
- result *= calcFalloff(h * mFalloff);
- }
-
- LLColor3 calcSigExt(const F32 h) const
- {
- return calcFalloff(h * mFalloff) * (1 + mAbsCoef) * mSigSca;
- }
-
- F32 calcPhase(const F32 cos_theta) const;
-
- static inline LLColor3 calcAirSca(const F32 h);
- static inline void calcAirSca(const F32 h, LLColor3 &result);
-
-private:
- static LLColor3 const sAirScaSeaLevel;
- static F32 const sAirScaIntense;
- static F32 const sAirScaAvg;
-
-protected:
- F32 mG;
- LLColor3 mSigSca;
- F32 mFalloff; // 1 - slow, >1 - faster
- F32 mAbsCoef;
+ const LLVector3& corner(const S32 n) const;
+ LLVector3& corner(const S32 n);
+ const LLVector3* corners() const;
};
-
class LLCubeMap;
-// turn on floating point precision
-// in vs2003 for this class. Otherwise
-// black dots go everywhere from 7:10 - 8:50
-#if LL_MSVC && __MSVC_VER__ < 8
-#pragma optimize("p", on)
-#endif
-
-
class LLVOSky : public LLStaticViewerObject
{
-public:
- /// WL PARAMS
- F32 dome_radius;
- F32 dome_offset_ratio;
- LLColor3 sunlight_color;
- LLColor3 ambient;
- F32 gamma;
- LLVector4 lightnorm;
- LLVector4 unclamped_lightnorm;
- LLColor3 blue_density;
- LLColor3 blue_horizon;
- F32 haze_density;
- F32 haze_horizon;
- F32 density_multiplier;
- F32 max_y;
- LLColor3 glow;
- F32 cloud_shadow;
- LLColor3 cloud_color;
- F32 cloud_scale;
- LLColor3 cloud_pos_density1;
- LLColor3 cloud_pos_density2;
-
-public:
- void initAtmospherics(void);
- void calcAtmospherics(void);
- LLColor3 createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient);
- LLColor3 createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient);
-
- void calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
- LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
- LLVector2 vary_HorizontalProjection[2]);
-
- LLColor3 calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
- LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
- LLVector2 vary_HorizontalProjection[2]);
-
-public:
+public:
enum
{
FACE_SIDE0,
@@ -447,7 +206,6 @@ public:
FACE_MOON, // was 7
FACE_BLOOM, // was 8
FACE_REFLECTION, // was 10
- FACE_DUMMY, //for an ATI bug --bao
FACE_COUNT
};
@@ -461,8 +219,10 @@ public:
void cleanupGL();
void restoreGL();
+ void calc();
+
/*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
- BOOL updateSky();
+ bool updateSky();
// Graphical stuff for objects - maybe broken out into render class
// later?
@@ -470,65 +230,31 @@ public:
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- void initSkyTextureDirs(const S32 side, const S32 tile);
- void createSkyTexture(const S32 side, const S32 tile);
-
- LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false);
-
- LLColor3 calcRadianceAtPoint(const LLVector3& pos) const
- {
- F32 radiance = mBrightnessScaleGuess * mSun.getIntensity();
- return LLColor3(radiance, radiance, radiance);
- }
-
- const LLHeavenBody& getSun() const { return mSun; }
+ const LLHeavenBody& getSun() const { return mSun; }
const LLHeavenBody& getMoon() const { return mMoon; }
- const LLVector3& getToSunLast() const { return mSun.getDirectionCached(); }
- const LLVector3& getToSun() const { return mSun.getDirection(); }
- const LLVector3& getToMoon() const { return mMoon.getDirection(); }
- const LLVector3& getToMoonLast() const { return mMoon.getDirectionCached(); }
- BOOL isSunUp() const { return mSun.getDirectionCached().mV[2] > -0.05f; }
- void calculateColors();
-
- LLColor3 getSunDiffuseColor() const { return mSunDiffuse; }
- LLColor3 getMoonDiffuseColor() const { return mMoonDiffuse; }
- LLColor4 getSunAmbientColor() const { return mSunAmbient; }
- LLColor4 getMoonAmbientColor() const { return mMoonAmbient; }
- const LLColor4& getTotalAmbientColor() const { return mTotalAmbient; }
- LLColor4 getFogColor() const { return mFogColor; }
- LLColor4 getGLFogColor() const { return mGLFogCol; }
-
- BOOL isSameFace(S32 idx, const LLFace* face) const { return mFace[idx] == face; }
-
- void initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity);
-
- void setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity);
+ bool isSameFace(S32 idx, const LLFace* face) const { return mFace[idx] == face; }
- BOOL updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 side, const BOOL is_sun,
- LLHeavenBody& hb, const F32 sin_max_angle,
- const LLVector3 &up, const LLVector3 &right);
+ // directions provided should already be in CFR coord sys (+x at, +z up, +y right)
+ void setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir, const LLVector3 &moon_dir);
+ void setSunDirectionCFR(const LLVector3 &sun_direction);
+ void setMoonDirectionCFR(const LLVector3 &moon_direction);
- F32 cosHorizon(const F32 delta = 0) const
- {
- const F32 sin_angle = EARTH_RADIUS/(EARTH_RADIUS + mCameraPosAgent.mV[2]);
- return delta - (F32)sqrt(1.f - sin_angle * sin_angle);
- }
-
- void updateSunHaloGeometry(LLDrawable *drawable);
+ bool updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const S32 side, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right);
void updateReflectionGeometry(LLDrawable *drawable, F32 H, const LLHeavenBody& HB);
-
- const LLHaze& getHaze() const { return mHaze; }
- LLHaze& getHaze() { return mHaze; }
- F32 getHazeConcentration() const { return mHazeConcentration; }
- void setHaze(const LLHaze& h) { mHaze = h; }
F32 getWorldScale() const { return mWorldScale; }
void setWorldScale(const F32 s) { mWorldScale = s; }
void updateFog(const F32 distance);
- void setFogRatio(const F32 fog_ratio) { mFogRatio = fog_ratio; }
- LLColor4U getFadeColor() const { return mFadeColor; }
- F32 getFogRatio() const { return mFogRatio; }
+
+ void setFogRatio(const F32 fog_ratio) { m_legacyAtmospherics.setFogRatio(fog_ratio); }
+ F32 getFogRatio() const { return m_legacyAtmospherics.getFogRatio(); }
+
+ LLColor4 getSkyFogColor() const { return m_legacyAtmospherics.getFogColor(); }
+ LLColor4 getGLFogColor() const { return m_legacyAtmospherics.getGLFogColor(); }
+
+ LLColor4U getFadeColor() const;
+
void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; }
void setWind ( const LLVector3& wind ) { mWind = wind.length(); }
@@ -538,24 +264,55 @@ public:
LLCubeMap *getCubeMap() const { return mCubeMap; }
S32 getDrawRefl() const { return mDrawRefl; }
void setDrawRefl(const S32 r) { mDrawRefl = r; }
- BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; }
+ bool isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; }
LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; }
- LLViewerTexture* getSunTex() const { return mSunTexturep; }
- LLViewerTexture* getMoonTex() const { return mMoonTexturep; }
- LLViewerTexture* getBloomTex() const { return mBloomTexturep; }
- void forceSkyUpdate(void) { mForceUpdate = TRUE; }
+ LLViewerTexture* getSunTex() const { return mSunTexturep[0]; }
+ LLViewerTexture* getMoonTex() const { return mMoonTexturep[0]; }
+ LLViewerTexture* getBloomTex() const { return mBloomTexturep[0]; }
+ LLViewerTexture* getCloudNoiseTex() const { return mCloudNoiseTexturep[0]; }
+
+ LLViewerTexture* getRainbowTex() const { return mRainbowMap; }
+ LLViewerTexture* getHaloTex() const { return mHaloMap; }
+
+ LLViewerTexture* getSunTexNext() const { return mSunTexturep[1]; }
+ LLViewerTexture* getMoonTexNext() const { return mMoonTexturep[1]; }
+ LLViewerTexture* getBloomTexNext() const { return mBloomTexturep[1]; }
+ LLViewerTexture* getCloudNoiseTexNext() const { return mCloudNoiseTexturep[1]; }
+
+ void setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next);
+ void setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next);
+ void setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next);
+ void setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next);
+
+ void setSunScale(F32 sun_scale);
+ void setMoonScale(F32 sun_scale);
+
+ void forceSkyUpdate(void);
public:
LLFace *mFace[FACE_COUNT];
LLVector3 mBumpSunDir;
+ F32 getInterpVal() const { return mInterpVal; }
+
protected:
~LLVOSky();
- LLPointer<LLViewerFetchedTexture> mSunTexturep;
- LLPointer<LLViewerFetchedTexture> mMoonTexturep;
- LLPointer<LLViewerFetchedTexture> mBloomTexturep;
+ void updateDirections(void);
+
+ void initSkyTextureDirs(const S32 side, const S32 tile);
+ void createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile);
+
+ LLPointer<LLViewerFetchedTexture> mSunTexturep[2];
+ LLPointer<LLViewerFetchedTexture> mMoonTexturep[2];
+ LLPointer<LLViewerFetchedTexture> mCloudNoiseTexturep[2];
+ LLPointer<LLViewerFetchedTexture> mBloomTexturep[2];
+ LLPointer<LLViewerFetchedTexture> mRainbowMap;
+ LLPointer<LLViewerFetchedTexture> mHaloMap;
+
+ F32 mSunScale = 1.0f;
+ F32 mMoonScale = 1.0f;
static S32 sResolution;
static S32 sTileResX;
@@ -575,73 +332,30 @@ protected:
LLColor3 mBrightestPointNew;
F32 mBrightnessScaleGuess;
LLColor3 mBrightestPointGuess;
- LLHaze mHaze;
- F32 mHazeConcentration;
- BOOL mWeatherChange;
+ bool mWeatherChange;
F32 mCloudDensity;
F32 mWind;
- BOOL mInitialized;
- BOOL mForceUpdate; //flag to force instantaneous update of cubemap
- LLVector3 mLastLightingDirection;
- LLColor3 mLastTotalAmbient;
+ bool mInitialized;
+ bool mForceUpdate;
+ bool mNeedUpdate; // flag to force update of cubemap
+ S32 mCubeMapUpdateStage; // state of cubemap uodate: -1 idle; 0-5 per-face updates; 6 finalizing
+
F32 mAmbientScale;
LLColor3 mNightColorShift;
F32 mInterpVal;
-
- LLColor4 mFogColor;
- LLColor4 mGLFogCol;
-
- F32 mFogRatio;
F32 mWorldScale;
- LLColor4 mSunAmbient;
- LLColor4 mMoonAmbient;
- LLColor4 mTotalAmbient;
- LLColor3 mSunDiffuse;
- LLColor3 mMoonDiffuse;
- LLColor4U mFadeColor; // Color to fade in from
-
- LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment
- S32 mDrawRefl;
+ LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment
+ S32 mDrawRefl;
LLFrameTimer mUpdateTimer;
+ LLTimer mForceUpdateThrottle;
+ bool mHeavenlyBodyUpdated ;
-public:
- //by bao
- //fake vertex buffer updating
- //to guarantee at least updating one VBO buffer every frame
- //to work around the bug caused by ATI card --> DEV-3855
- //
- void createDummyVertexBuffer() ;
- void updateDummyVertexBuffer() ;
-
- BOOL mHeavenlyBodyUpdated ;
+ AtmosphericsVars m_atmosphericsVars;
+ AtmosphericsVars m_lastAtmosphericsVars;
+ LLAtmospherics m_legacyAtmospherics;
};
-// turn it off
-#if LL_MSVC && __MSVC_VER__ < 8
-#pragma optimize("p", off)
-#endif
-
-// Utility functions
-F32 azimuth(const LLVector3 &v);
-F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE);
-
-
-/* Proportion of light that is scattered into 'path' from 'in' over distance dt. */
-/* assumes that vectors 'path' and 'in' are normalized. Scattering coef / 2pi */
-
-inline LLColor3 LLHaze::calcAirSca(const F32 h)
-{
- return calcFalloff(h) * sAirScaSeaLevel;
-}
-
-inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result)
-{
- result = sAirScaSeaLevel;
- result *= calcFalloff(h);
-}
-
-
#endif
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 369ddebe2d..41099cb570 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -45,6 +45,8 @@
#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
+#include "llvolumemgr.h"
+#include "llvovolume.h"
#include "llworld.h"
#include "noise.h"
#include "pipeline.h"
@@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region
mFrameCount = 0;
mWind = mRegionp->mWind.getVelocity(getPositionRegion());
mTrunkLOD = 0;
+
+ // if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels
+ llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS);
}
@@ -347,8 +352,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
return;
}
- S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ;
+ S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled
F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;
+ F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f);
+ F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter
+ F32 sz = mBillboardScale * mBillboardRatio * diameter;
for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)
{
@@ -357,7 +365,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
trunk_LOD = j;
break;
}
- }
+ }
+
+ F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance;
+ S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality
+
+ // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels
+ trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1);
+ trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS);
if (mReferenceBuffer.isNull())
{
@@ -408,8 +423,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
LLVector3 lookAt = center - viewer_pos_agent;
F32 dist = lookAt.normVec() ;
F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;
-
- F32 range = dist - getMinScale()/2;
+ F32 radius = getScale().length()*0.5f;
+ F32 range = dist - radius;
+
if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero
{
mAppAngle = 180.f;
@@ -536,12 +552,14 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
LLStrider<LLVector3> vertices;
LLStrider<LLVector3> normals;
+ LLStrider<LLColor4U> colors;
LLStrider<LLVector2> tex_coords;
LLStrider<U16> indicesp;
mReferenceBuffer->getVertexStrider(vertices);
mReferenceBuffer->getNormalStrider(normals);
mReferenceBuffer->getTexCoord0Strider(tex_coords);
+ mReferenceBuffer->getColorStrider(colors);
mReferenceBuffer->getIndexStrider(indicesp);
S32 vertex_count = 0;
@@ -551,24 +569,27 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
*(normals++) = LLVector3(-SRR2, -SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
*(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR3, -SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
*(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(-SRR3, -SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
*(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR2, -SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
-
-
+
*(indicesp++) = 0;
index_count++;
*(indicesp++) = 1;
@@ -587,21 +608,25 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
*(normals++) = LLVector3(-SRR2, SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
*(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR3, SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
*(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(-SRR3, SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
*(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR2, SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(indicesp++) = 4;
@@ -623,21 +648,25 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
*(normals++) = LLVector3(SRR2, -SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR3, SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
*(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR3, -SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
*(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(SRR2, SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(indicesp++) = 8;
@@ -659,21 +688,25 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
*(normals++) = LLVector3(-SRR2, -SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(-SRR3, SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
*(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(-SRR3, -SRR3, SRR3);
*(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
*(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(normals++) = LLVector3(-SRR2, SRR2, 0.f);
*(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
*(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f);
+ *(colors++) = LLColor4U::white;
vertex_count++;
*(indicesp++) = 12;
@@ -786,6 +819,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
*(vertices++) = LLVector3(x1*radius, y1*radius, z);
*(normals++) = LLVector3(x1, y1, 0.f);
*(tex_coords++) = tc;
+ *(colors++) = LLColor4U::white;
vertex_count++;
}
}
@@ -910,15 +944,17 @@ void LLVOTree::updateMesh()
LLStrider<LLVector3> vertices;
LLStrider<LLVector3> normals;
LLStrider<LLVector2> tex_coords;
+ LLStrider<LLColor4U> colors;
LLStrider<U16> indices;
U16 idx_offset = 0;
buff->getVertexStrider(vertices);
buff->getNormalStrider(normals);
buff->getTexCoord0Strider(tex_coords);
+ buff->getColorStrider(colors);
buff->getIndexStrider(indices);
- genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha);
+ genBranchPipeline(vertices, normals, tex_coords, colors, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha);
mReferenceBuffer->flush();
buff->flush();
@@ -927,6 +963,7 @@ void LLVOTree::updateMesh()
void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
LLStrider<LLVector3>& normals,
LLStrider<LLVector2>& tex_coords,
+ LLStrider<LLColor4U>& colors,
LLStrider<U16>& indices,
U16& cur_idx,
LLMatrix4& matrix,
@@ -939,11 +976,13 @@ void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
LLStrider<LLVector3> v;
LLStrider<LLVector3> n;
LLStrider<LLVector2> t;
+ LLStrider<LLColor4U> c;
LLStrider<U16> idx;
mReferenceBuffer->getVertexStrider(v);
mReferenceBuffer->getNormalStrider(n);
mReferenceBuffer->getTexCoord0Strider(t);
+ mReferenceBuffer->getColorStrider(c);
mReferenceBuffer->getIndexStrider(idx);
//copy/transform vertices into mesh - check
@@ -955,6 +994,7 @@ void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
norm.normalize();
*normals++ = norm;
*tex_coords++ = t[index];
+ *colors++ = c[index];
}
//copy offset indices into mesh - check
@@ -972,6 +1012,7 @@ void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
LLStrider<LLVector3>& normals,
LLStrider<LLVector2>& tex_coords,
+ LLStrider<LLColor4U>& colors,
LLStrider<U16>& indices,
U16& index_offset,
LLMatrix4& matrix,
@@ -1013,7 +1054,7 @@ void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m);
norm_mat.invert();
- appendMesh(vertices, normals, tex_coords, indices, index_offset, scale_mat, norm_mat,
+ appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat,
sLODVertexOffset[trunk_LOD], sLODVertexCount[trunk_LOD], sLODIndexCount[trunk_LOD], sLODIndexOffset[trunk_LOD]);
}
@@ -1032,7 +1073,7 @@ void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
LLMatrix4 rot_mat(rot);
rot_mat *= trans_mat;
- genBranchPipeline(vertices, normals, tex_coords, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha);
+ genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha);
}
// Recurse to continue trunk
if (trunk_depth)
@@ -1043,7 +1084,7 @@ void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1));
rot_mat *= trans_mat; // rotate a bit around Z when ascending
- genBranchPipeline(vertices, normals, tex_coords, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha);
+ genBranchPipeline(vertices, normals, tex_coords, colors, indices, index_offset, rot_mat, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha);
}
}
else
@@ -1062,7 +1103,7 @@ void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
glh::matrix4f norm((F32*) scale_mat.mMatrix);
LLMatrix4 norm_mat = LLMatrix4(norm.inverse().transpose().m);
- appendMesh(vertices, normals, tex_coords, indices, index_offset, scale_mat, norm_mat, 0, LEAF_VERTICES, LEAF_INDICES, 0);
+ appendMesh(vertices, normals, tex_coords, colors, indices, index_offset, scale_mat, norm_mat, 0, LEAF_VERTICES, LEAF_INDICES, 0);
}
}
}
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index c16ed70bb4..93c22d2da3 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -79,7 +79,8 @@ public:
void appendMesh(LLStrider<LLVector3>& vertices,
LLStrider<LLVector3>& normals,
- LLStrider<LLVector2>& tex_coords,
+ LLStrider<LLVector2>& tex_coords,
+ LLStrider<LLColor4U>& colors,
LLStrider<U16>& indices,
U16& idx_offset,
LLMatrix4& matrix,
@@ -92,6 +93,7 @@ public:
void genBranchPipeline(LLStrider<LLVector3>& vertices,
LLStrider<LLVector3>& normals,
LLStrider<LLVector2>& tex_coords,
+ LLStrider<LLColor4U>& colors,
LLStrider<U16>& indices,
U16& index_offset,
LLMatrix4& matrix,
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 0a1efd564f..3bdb8a2981 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -235,7 +235,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mLastFetchedMediaVersion = -1;
memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mMDCImplCount = 0;
- mLastRiggingInfoLOD = -1;
+ mLastRiggingInfoLOD = -1;
+ mResetDebugText = false;
}
LLVOVolume::~LLVOVolume()
@@ -261,7 +262,10 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
- LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
+ if (getVolume())
+ {
+ LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
+ }
if(getMDCImplCount() > 0)
{
@@ -691,6 +695,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
LL_RECORD_BLOCK_TIME(FTM_VOLUME_TEXTURES);
// Update the pixel area of all faces
+ if (mDrawable.isNull())
+ {
+ return;
+ }
+
if(!forced)
{
if(!isVisible())
@@ -1388,6 +1397,15 @@ BOOL LLVOVolume::calcLOD()
{
std::string debug_object_text = get_debug_object_lod_text(this);
setDebugText(debug_object_text);
+ mResetDebugText = true;
+ }
+ }
+ else
+ {
+ if (mResetDebugText)
+ {
+ restoreHudText();
+ mResetDebugText = false;
}
}
@@ -2063,7 +2081,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
}
else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
{
- U8 end = mMediaImplList.size() ;
+ U8 end = (U8)(mMediaImplList.size()) ;
for(U8 i = num_tes; i < end ; i++)
{
removeMediaImpl(i) ;
@@ -3147,14 +3165,19 @@ void LLVOVolume::setIsLight(BOOL is_light)
}
}
-void LLVOVolume::setLightColor(const LLColor3& color)
+void LLVOVolume::setLightSRGBColor(const LLColor3& color)
+{
+ setLightLinearColor(linearColor3(color));
+}
+
+void LLVOVolume::setLightLinearColor(const LLColor3& color)
{
LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
if (param_block)
{
- if (param_block->getColor() != color)
+ if (param_block->getLinearColor() != color)
{
- param_block->setColor(LLColor4(color, param_block->getColor().mV[3]));
+ param_block->setLinearColor(LLColor4(color, param_block->getLinearColor().mV[3]));
parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
@@ -3167,9 +3190,9 @@ void LLVOVolume::setLightIntensity(F32 intensity)
LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
if (param_block)
{
- if (param_block->getColor().mV[3] != intensity)
+ if (param_block->getLinearColor().mV[3] != intensity)
{
- param_block->setColor(LLColor4(LLColor3(param_block->getColor()), intensity));
+ param_block->setLinearColor(LLColor4(LLColor3(param_block->getLinearColor()), intensity));
parameterChanged(LLNetworkData::PARAMS_LIGHT, true);
}
}
@@ -3221,25 +3244,17 @@ BOOL LLVOVolume::getIsLight() const
return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
}
-LLColor3 LLVOVolume::getLightBaseColor() const
+LLColor3 LLVOVolume::getLightSRGBBaseColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
- if (param_block)
- {
- return LLColor3(param_block->getColor());
- }
- else
- {
- return LLColor3(1,1,1);
- }
+ return srgbColor3(getLightLinearBaseColor());
}
-LLColor3 LLVOVolume::getLightColor() const
+LLColor3 LLVOVolume::getLightLinearBaseColor() const
{
const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
if (param_block)
{
- return LLColor3(param_block->getColor()) * param_block->getColor().mV[3];
+ return LLColor3(param_block->getLinearColor());
}
else
{
@@ -3247,6 +3262,26 @@ LLColor3 LLVOVolume::getLightColor() const
}
}
+LLColor3 LLVOVolume::getLightLinearColor() const
+{
+ const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ if (param_block)
+ {
+ return LLColor3(param_block->getLinearColor()) * param_block->getLinearColor().mV[3];
+ }
+ else
+ {
+ return LLColor3(1, 1, 1);
+ }
+}
+
+LLColor3 LLVOVolume::getLightSRGBColor() const
+{
+ LLColor3 ret = getLightLinearColor();
+ ret = srgbColor3(ret);
+ return ret;
+}
+
LLUUID LLVOVolume::getLightTextureID() const
{
if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
@@ -3283,18 +3318,16 @@ F32 LLVOVolume::getSpotLightPriority() const
void LLVOVolume::updateSpotLightPriority()
{
+ F32 r = getLightRadius();
LLVector3 pos = mDrawable->getPositionAgent();
+
LLVector3 at(0,0,-1);
at *= getRenderRotation();
-
- F32 r = getLightRadius()*0.5f;
-
pos += at * r;
at = LLViewerCamera::getInstance()->getAtAxis();
-
pos -= at * r;
-
+
mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance());
if (mLightTexture.notNull())
@@ -3340,7 +3373,7 @@ F32 LLVOVolume::getLightIntensity() const
const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
if (param_block)
{
- return param_block->getColor().mV[3];
+ return param_block->getLinearColor().mV[3];
}
else
{
@@ -3361,12 +3394,12 @@ F32 LLVOVolume::getLightRadius() const
}
}
-F32 LLVOVolume::getLightFalloff() const
+F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
{
const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
if (param_block)
{
- return param_block->getFalloff();
+ return param_block->getFalloff() * fudge_factor;
}
else
{
@@ -4567,20 +4600,19 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
U8 mode = mat->getDiffuseAlphaMode();
- if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE ||
- mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
+ || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
+ || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0))
{
ignore_alpha = true;
}
}
}
+ BOOL no_texture = !face->getTexture() || !face->getTexture()->hasGLTexture();
+ BOOL mask = no_texture ? FALSE : face->getTexture()->getMask(face->surfaceToTexture(tc, p, n));
if (face &&
- (ignore_alpha ||
- pick_transparent ||
- !face->getTexture() ||
- !face->getTexture()->hasGLTexture() ||
- face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
+ (ignore_alpha || pick_transparent || no_texture || mask))
{
local_end = p;
if (face_hitp != NULL)
@@ -4785,18 +4817,44 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
U32 max_joints = LLSkinningUtil::getMaxJointCount();
rigged_vert_count += dst_face.mNumVertices;
rigged_face_count++;
- for (U32 j = 0; j < dst_face.mNumVertices; ++j)
- {
- LLMatrix4a final_mat;
- LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
+
+ #if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
+ if (vol_face.mJointIndices) // fast path with preconditioned joint indices
+ {
+ LLMatrix4a src[4];
+ U8* joint_indices_cursor = vol_face.mJointIndices;
+ LLVector4a* just_weights = vol_face.mJustWeights;
+ for (U32 j = 0; j < dst_face.mNumVertices; ++j)
+ {
+ LLMatrix4a final_mat;
+ F32* w = just_weights[j].getF32ptr();
+ LLSkinningUtil::getPerVertexSkinMatrixWithIndices(w, joint_indices_cursor, mat, final_mat, src);
+ joint_indices_cursor += 4;
+
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+ }
+ }
+ else
+ #endif
+ {
+ for (U32 j = 0; j < dst_face.mNumVertices; ++j)
+ {
+ LLMatrix4a final_mat;
+ LLSkinningUtil::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
- LLVector4a& v = vol_face.mPositions[j];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
- }
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+ }
+ }
//update bounding box
// VFExtents change
@@ -4850,6 +4908,14 @@ U32 LLVOVolume::getPartitionType() const
{
return LLViewerRegion::PARTITION_HUD;
}
+ if (isAnimatedObject() && getControlAvatar())
+ {
+ return LLViewerRegion::PARTITION_CONTROL_AV;
+ }
+ if (isAttachment())
+ {
+ return LLViewerRegion::PARTITION_AVATAR;
+ }
return LLViewerRegion::PARTITION_VOLUME;
}
@@ -4880,6 +4946,20 @@ LLVolumeGeometryManager()
mSlopRatio = 0.25f;
}
+LLAvatarBridge::LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+ : LLVolumeBridge(drawablep, regionp)
+{
+ mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
+ mPartitionType = LLViewerRegion::PARTITION_AVATAR;
+}
+
+LLControlAVBridge::LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+ : LLVolumeBridge(drawablep, regionp)
+{
+ mDrawableType = LLPipeline::RENDER_TYPE_CONTROL_AV;
+ mPartitionType = LLViewerRegion::PARTITION_CONTROL_AV;
+}
+
bool can_batch_texture(LLFace* facep)
{
if (facep->getTextureEntry()->getBumpmap())
@@ -4977,7 +5057,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if ( type == LLRenderPass::PASS_ALPHA
&& facep->getTextureEntry()->getMaterialParams().notNull()
&& !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)
- && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1)
+ && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1)
{
LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
}
@@ -5058,7 +5138,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
- if (index < 255 && idx >= 0)
+ if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
{
if (mat || draw_vec[idx]->mMaterial)
{ //can't batch textures when materials are present (yet)
@@ -5104,7 +5184,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd += facep->getGeomCount();
draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
- if (index < 255 && index >= draw_vec[idx]->mTextureList.size())
+ if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size())
{
draw_vec[idx]->mTextureList.resize(index+1);
draw_vec[idx]->mTextureList[index] = tex;
@@ -5191,7 +5271,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;
}
- if (index < 255)
+ if (index < FACE_DO_NOT_BATCH_TEXTURES)
{ //initialize texture list for texture batching
draw_info->mTextureList.resize(index+1);
draw_info->mTextureList[index] = tex;
@@ -5224,7 +5304,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
LLDrawPool* drawpool = face->getPool();
if (drawpool)
{
- if (drawpool->getType() == LLDrawPool::POOL_AVATAR)
+ if (drawpool->getType() == LLDrawPool::POOL_AVATAR
+ || drawpool->getType() == LLDrawPool::POOL_CONTROL_AV)
{
return (LLDrawPoolAvatar*) drawpool;
}
@@ -5503,7 +5584,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//remove face from old pool if it exists
LLDrawPool* old_pool = facep->getPool();
- if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ if (old_pool
+ && (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV))
{
((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
}
@@ -5512,6 +5594,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLViewerTexture* tex = facep->getTexture();
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ F32 te_alpha = te->getColor().mV[3];
if (te->getGlow())
{
@@ -5519,6 +5602,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
LLMaterial* mat = te->getMaterialParams().get();
+ bool fullbright = te->getFullbright();
if (mat && LLPipeline::sRenderDeferred)
{
@@ -5526,14 +5610,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
- te->getColor().mV[3] < 0.999f);
+ te_alpha < 0.999f);
if (is_alpha)
{ //this face needs alpha blending, override alpha mode
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
}
- if (!is_alpha || te->getColor().mV[3] > 0.f) // //only add the face if it will actually be visible
+ if (fullbright && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE))
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
+ }
+ else if (!is_alpha || te_alpha > 0.f) // //only add the face if it will actually be visible
{
U32 mask = mat->getShaderMask(alpha_mode);
pool->addRiggedFace(facep, mask);
@@ -5545,8 +5633,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
else if (mat)
- {
- bool fullbright = te->getFullbright();
+ {
bool is_alpha = type == LLDrawPool::POOL_ALPHA;
U8 mode = mat->getDiffuseAlphaMode();
bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
@@ -5883,7 +5970,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
}
- BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
+ BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
if (batch_textures)
{
@@ -6318,7 +6405,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//face has no texture index
facep->mDrawInfo = NULL;
- facep->setTextureIndex(255);
+ facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
if (geom_count + facep->getGeomCount() > max_vertices)
{ //cut batches on geom count too big
@@ -6382,7 +6469,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
facep->setGeomIndex(index_offset);
facep->setVertexBuffer(buffer);
- if (batch_textures && facep->getTextureIndex() == 255)
+ if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES)
{
LL_ERRS() << "Invalid texture index." << LL_ENDL;
}
@@ -6451,8 +6538,12 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
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());
- bool opaque = te->getColor().mV[3] >= 0.999f;
+ bool opaque = te_alpha >= 0.999f;
+ bool transparent = te_alpha < 0.999f;
+
+ is_alpha = (is_alpha || transparent) ? TRUE : FALSE;
if (mat && LLPipeline::sRenderDeferred && !hud_group)
{
@@ -6481,14 +6572,20 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
else
{
- if (mat->getEnvironmentIntensity() > 0 ||
- te->getShiny() > 0)
+ if (mat->getEnvironmentIntensity() > 0 || te->getShiny() > 0)
{
material_pass = true;
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ if (opaque)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
}
}
}
@@ -6496,7 +6593,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
- else if (te->getColor().mV[3] < 0.999f)
+ else if (transparent)
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
@@ -6544,7 +6641,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
else if (mat)
{
U8 mode = mat->getDiffuseAlphaMode();
- if (te->getColor().mV[3] < 0.999f)
+
+ is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND));
+
+ if (is_alpha)
{
mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
}
@@ -6553,7 +6653,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK);
}
- else if (is_alpha || (te->getColor().mV[3] < 0.999f))
+ else if (is_alpha )
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
@@ -6669,7 +6769,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
- }
+ }
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 13db9c39b7..ce400a3498 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -242,7 +242,11 @@ public:
// For Lights
void setIsLight(BOOL is_light);
- void setLightColor(const LLColor3& color);
+ //set the gamma-corrected (sRGB) color of this light
+ void setLightSRGBColor(const LLColor3& color);
+ //set the linear color of this light
+ void setLightLinearColor(const LLColor3& color);
+
void setLightIntensity(F32 intensity);
void setLightRadius(F32 radius);
void setLightFalloff(F32 falloff);
@@ -251,8 +255,21 @@ public:
void setSpotLightParams(LLVector3 params);
BOOL getIsLight() const;
- LLColor3 getLightBaseColor() const; // not scaled by intensity
- LLColor3 getLightColor() const; // scaled by intensity
+
+
+ // Get the light color in sRGB color space NOT scaled by intensity.
+ LLColor3 getLightSRGBBaseColor() const;
+
+ // Get the light color in linear color space NOT scaled by intensity.
+ LLColor3 getLightLinearBaseColor() const;
+
+ // Get the light color in linear color space scaled by intensity
+ // this is the value that should be fed into shaders
+ LLColor3 getLightLinearColor() const;
+
+ // Get the light color in sRGB color space scaled by intensity.
+ LLColor3 getLightSRGBColor() const;
+
LLUUID getLightTextureID() const;
bool isLightSpotlight() const;
LLVector3 getSpotLightParams() const;
@@ -262,7 +279,7 @@ public:
LLViewerTexture* getLightTexture();
F32 getLightIntensity() const;
F32 getLightRadius() const;
- F32 getLightFalloff() const;
+ F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
// Flexible Objects
@@ -407,6 +424,8 @@ private:
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
+ bool mResetDebugText;
+
LLPointer<LLRiggedVolume> mRiggedVolume;
// statics
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index ccda92810e..12def24a0d 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -145,7 +145,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
static const unsigned int vertices_per_quad = 4;
static const unsigned int indices_per_quad = 6;
- const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && LLGLSLShader::sNoFixedFunction ? 16 : 1;
+ const S32 size = LLPipeline::sRenderTransparentWater && LLGLSLShader::sNoFixedFunction ? 16 : 1;
const S32 num_quads = size * size;
face->setSize(vertices_per_quad * num_quads,
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 2cb5fc81b0..d428cb1568 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -32,14 +32,12 @@
#include "llsky.h"
#include "lldrawpoolwlsky.h"
#include "llface.h"
-#include "llwlparammanager.h"
#include "llviewercontrol.h"
+#include "llenvironment.h"
+#include "llsettingssky.h"
-#define DOME_SLICES 1
-const F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f;
-
-const U32 LLVOWLSky::MIN_SKY_DETAIL = 3;
-const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
+static const U32 MIN_SKY_DETAIL = 8;
+static const U32 MAX_SKY_DETAIL = 180;
inline U32 LLVOWLSky::getNumStacks(void)
{
@@ -51,16 +49,6 @@ inline U32 LLVOWLSky::getNumSlices(void)
return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
}
-inline U32 LLVOWLSky::getFanNumVerts(void)
-{
- return getNumSlices() + 1;
-}
-
-inline U32 LLVOWLSky::getFanNumIndices(void)
-{
- return getNumSlices() * 3;
-}
-
inline U32 LLVOWLSky::getStripsNumVerts(void)
{
return (getNumStacks() - 1) * getNumSlices();
@@ -87,11 +75,6 @@ LLVOWLSky::LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi
initStars();
}
-void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction,
- LLVector3 const & sun_angular_velocity)
-{
-}
-
void LLVOWLSky::idleUpdate(LLAgent &agent, const F64 &time)
{
@@ -116,12 +99,16 @@ LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline)
inline F32 LLVOWLSky::calcPhi(U32 i)
{
+ // Calc: PI/8 * 1-((1-t^4)*(1-t^4)) { 0<t<1 }
+ // Demos: \pi/8*\left(1-((1-x^{4})*(1-x^{4}))\right)\ \left\{0<x\le1\right\}
+
// i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f]
F32 t = float(i) / float(getNumStacks());
// ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex)
- t = t*t*t*t;
-
+ t *= t;
+ t *= t;
+
// invert and square the parameter of the tesselation to bias things toward 1 (the horizon)
t = 1.f - t;
t = t*t;
@@ -130,167 +117,20 @@ inline F32 LLVOWLSky::calcPhi(U32 i)
return (F_PI / 8.f) * t;
}
-#if !DOME_SLICES
-static const F32 Q = (1.f + sqrtf(5.f))/2.f; //golden ratio
-
-//icosahedron verts (based on asset b0c7b76e-28c6-1f87-a1de-752d5e3cd264, contact Runitai Linden for a copy)
-static const LLVector3 icosahedron_vert[] =
-{
- LLVector3(0,1.f,Q),
- LLVector3(0,-1.f,Q),
- LLVector3(0,-1.f,-Q),
- LLVector3(0,1.f,-Q),
-
- LLVector3(Q,0,1.f),
- LLVector3(-Q,0,1.f),
- LLVector3(-Q,0,-1.f),
- LLVector3(Q,0,-1.f),
-
- LLVector3(1,-Q,0.f),
- LLVector3(-1,-Q,0.f),
- LLVector3(-1,Q,0.f),
- LLVector3(1,Q,0.f),
-};
-
-//indices
-static const U32 icosahedron_ind[] =
-{
- 5,0,1,
- 10,0,5,
- 5,1,9,
- 10,5,6,
- 6,5,9,
- 11,0,10,
- 3,11,10,
- 3,10,6,
- 3,6,2,
- 7,3,2,
- 8,7,2,
- 4,7,8,
- 1,4,8,
- 9,8,2,
- 9,2,6,
- 11,3,7,
- 4,0,11,
- 4,11,7,
- 1,0,4,
- 1,8,9,
-};
-
-
-//split every triangle in LLVertexBuffer into even fourths (assumes index triangle lists)
-void subdivide(LLVertexBuffer& in, LLVertexBuffer* ret)
-{
- S32 tri_in = in.getNumIndices()/3;
-
- ret->allocateBuffer(tri_in*4*3, tri_in*4*3, TRUE);
-
- LLStrider<LLVector3> vin, vout;
- LLStrider<U16> indin, indout;
-
- ret->getVertexStrider(vout);
- in.getVertexStrider(vin);
-
- ret->getIndexStrider(indout);
- in.getIndexStrider(indin);
-
-
- for (S32 i = 0; i < tri_in; i++)
- {
- LLVector3 v0 = vin[*indin++];
- LLVector3 v1 = vin[*indin++];
- LLVector3 v2 = vin[*indin++];
-
- LLVector3 v3 = (v0 + v1) * 0.5f;
- LLVector3 v4 = (v1 + v2) * 0.5f;
- LLVector3 v5 = (v2 + v0) * 0.5f;
-
- *vout++ = v0;
- *vout++ = v3;
- *vout++ = v5;
-
- *vout++ = v3;
- *vout++ = v4;
- *vout++ = v5;
-
- *vout++ = v3;
- *vout++ = v1;
- *vout++ = v4;
-
- *vout++ = v5;
- *vout++ = v4;
- *vout++ = v2;
- }
-
- for (S32 i = 0; i < ret->getNumIndices(); i++)
- {
- *indout++ = i;
- }
-
-}
-
-void chop(LLVertexBuffer& in, LLVertexBuffer* out)
-{
- //chop off all triangles below horizon
- F32 d = LLWLParamManager::sParamMgr->getDomeOffset() * LLWLParamManager::sParamMgr->getDomeRadius();
-
- std::vector<LLVector3> vert;
-
- LLStrider<LLVector3> vin;
- LLStrider<U16> index;
-
- in.getVertexStrider(vin);
- in.getIndexStrider(index);
-
- U32 tri_count = in.getNumIndices()/3;
- for (U32 i = 0; i < tri_count; i++)
- {
- LLVector3 &v1 = vin[index[i*3+0]];
- LLVector3 &v2 = vin[index[i*3+1]];
- LLVector3 &v3 = vin[index[i*3+2]];
-
- if (v1.mV[1] > d ||
- v2.mV[1] > d ||
- v3.mV[1] > d)
- {
- v1.mV[1] = llmax(v1.mV[1], d);
- v2.mV[1] = llmax(v1.mV[1], d);
- v3.mV[1] = llmax(v1.mV[1], d);
-
- vert.push_back(v1);
- vert.push_back(v2);
- vert.push_back(v3);
- }
- }
-
- out->allocateBuffer(vert.size(), vert.size(), TRUE);
-
- LLStrider<LLVector3> vout;
- out->getVertexStrider(vout);
- out->getIndexStrider(index);
-
- for (U32 i = 0; i < vert.size(); i++)
- {
- *vout++ = vert[i];
- *index++ = i;
- }
-}
-#endif // !DOME_SLICES
-
void LLVOWLSky::resetVertexBuffers()
{
- mFanVerts = NULL;
mStripsVerts.clear();
- mStarsVerts = NULL;
+ mStarsVerts = nullptr;
+ mFsSkyVerts = nullptr;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
void LLVOWLSky::cleanupGL()
{
- mFanVerts = NULL;
mStripsVerts.clear();
- mStarsVerts = NULL;
+ mStarsVerts = nullptr;
+ mFsSkyVerts = nullptr;
LLDrawPoolWLSky::cleanupGL();
}
@@ -305,38 +145,51 @@ static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Windlight Sky Geometry");
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
{
- LL_RECORD_BLOCK_TIME(FTM_GEO_SKY);
+ LL_RECORD_BLOCK_TIME(FTM_GEO_SKY);
LLStrider<LLVector3> vertices;
LLStrider<LLVector2> texCoords;
LLStrider<U16> indices;
-#if DOME_SLICES
- {
- mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
- if (!mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE))
+ if (mFsSkyVerts.isNull())
+ {
+ mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+
+ if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE))
{
- LL_WARNS() << "Failed to allocate Vertex Buffer on sky update to "
- << getFanNumVerts() << " vertices and "
- << getFanNumIndices() << " indices" << LL_ENDL;
+ LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL;
}
- BOOL success = mFanVerts->getVertexStrider(vertices)
- && mFanVerts->getTexCoord0Strider(texCoords)
- && mFanVerts->getIndexStrider(indices);
+ BOOL success = mFsSkyVerts->getVertexStrider(vertices)
+ && mFsSkyVerts->getTexCoord0Strider(texCoords)
+ && mFsSkyVerts->getIndexStrider(indices);
if(!success)
{
- LL_ERRS() << "Failed updating WindLight sky geometry." << LL_ENDL;
+ LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL;
}
- buildFanBuffer(vertices, texCoords, indices);
+ *vertices++ = LLVector3(-1.0f, -1.0f, 0.0f);
+ *vertices++ = LLVector3( 1.0f, -1.0f, 0.0f);
+ *vertices++ = LLVector3(-1.0f, 1.0f, 0.0f);
+ *vertices++ = LLVector3( 1.0f, 1.0f, 0.0f);
- mFanVerts->flush();
- }
+ *texCoords++ = LLVector2(0.0f, 0.0f);
+ *texCoords++ = LLVector2(1.0f, 0.0f);
+ *texCoords++ = LLVector2(0.0f, 1.0f);
+ *texCoords++ = LLVector2(1.0f, 1.0f);
+
+ *indices++ = 0;
+ *indices++ = 1;
+ *indices++ = 2;
+ *indices++ = 1;
+ *indices++ = 3;
+ *indices++ = 2;
+
+ mFsSkyVerts->flush();
+ }
{
- LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
- const U32 max_buffer_bytes = max_vbo_size * 1024;
+ const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);
@@ -398,8 +251,11 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
LL_ERRS() << "Failed updating WindLight sky geometry." << LL_ENDL;
}
+ U32 vertex_count = 0;
+ U32 index_count = 0;
+
// fill it
- buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices);
+ buildStripsBuffer(begin_stack, end_stack, vertex_count, index_count, vertices, texCoords, indices);
// and unlock the buffer
segment->flush();
@@ -407,85 +263,6 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
LL_INFOS() << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << LL_ENDL;
}
-#else
- mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
-
- const F32 RADIUS = LLWLParamManager::sParamMgr->getDomeRadius();
-
- LLPointer<LLVertexBuffer> temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
- temp->allocateBuffer(12, 60, TRUE);
-
- BOOL success = temp->getVertexStrider(vertices)
- && temp->getIndexStrider(indices);
-
- if (success)
- {
- for (U32 i = 0; i < 12; i++)
- {
- *vertices++ = icosahedron_vert[i];
- }
-
- for (U32 i = 0; i < 60; i++)
- {
- *indices++ = icosahedron_ind[i];
- }
- }
-
-
- LLPointer<LLVertexBuffer> temp2;
-
- for (U32 i = 0; i < 8; i++)
- {
- temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
- subdivide(*temp, temp2);
- temp = temp2;
- }
-
- temp->getVertexStrider(vertices);
- for (S32 i = 0; i < temp->getNumVerts(); i++)
- {
- LLVector3 v = vertices[i];
- v.normVec();
- vertices[i] = v*RADIUS;
- }
-
- temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
- chop(*temp, temp2);
-
- mStripsVerts->allocateBuffer(temp2->getNumVerts(), temp2->getNumIndices(), TRUE);
-
- success = mStripsVerts->getVertexStrider(vertices)
- && mStripsVerts->getTexCoordStrider(texCoords)
- && mStripsVerts->getIndexStrider(indices);
-
- LLStrider<LLVector3> v;
- temp2->getVertexStrider(v);
- LLStrider<U16> ind;
- temp2->getIndexStrider(ind);
-
- if (success)
- {
- for (S32 i = 0; i < temp2->getNumVerts(); ++i)
- {
- LLVector3 vert = *v++;
- vert.normVec();
- F32 z0 = vert.mV[2];
- F32 x0 = vert.mV[0];
-
- vert *= RADIUS;
-
- *vertices++ = vert;
- *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
- }
-
- for (S32 i = 0; i < temp2->getNumIndices(); ++i)
- {
- *indices++ = *ind++;
- }
- }
-
- mStripsVerts->flush();
-#endif
updateStarColors();
updateStarGeometry(drawable);
@@ -505,6 +282,21 @@ void LLVOWLSky::drawStars(void)
}
}
+void LLVOWLSky::drawFsSky(void)
+{
+ if (mFsSkyVerts.isNull())
+ {
+ updateGeometry(mDrawable);
+ }
+
+ LLGLDisable disable_blend(GL_BLEND);
+
+ mFsSkyVerts->setBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK);
+ mFsSkyVerts->drawRange(LLRender::TRIANGLES, 0, mFsSkyVerts->getNumVerts() - 1, mFsSkyVerts->getNumIndices(), 0);
+ gPipeline.addTrianglesDrawn(mFsSkyVerts->getNumIndices(), LLRender::TRIANGLES);
+ LLVertexBuffer::unbind();
+}
+
void LLVOWLSky::drawDome(void)
{
if (mStripsVerts.empty())
@@ -516,7 +308,6 @@ void LLVOWLSky::drawDome(void)
const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
-#if DOME_SLICES
std::vector< LLPointer<LLVertexBuffer> >::const_iterator strips_vbo_iter, end_strips;
end_strips = mStripsVerts.end();
for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter)
@@ -532,21 +323,13 @@ void LLVOWLSky::drawDome(void)
gPipeline.addTrianglesDrawn(strips_segment->getNumIndices(), LLRender::TRIANGLE_STRIP);
}
-#else
- mStripsVerts->setBuffer(data_mask);
- gGL.syncMatrices();
- glDrawRangeElements(
- GL_TRIANGLES,
- 0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(),
- GL_UNSIGNED_SHORT,
- mStripsVerts->getIndicesPointer());
-#endif
-
LLVertexBuffer::unbind();
}
void LLVOWLSky::initStars()
{
+ const F32 DISTANCE_TO_STARS = LLEnvironment::instance().getCurrentSky()->getDomeRadius();
+
// Initialize star map
mStarVertices.resize(getStarsNumVerts());
mStarColors.resize(getStarsNumVerts());
@@ -581,72 +364,15 @@ void LLVOWLSky::initStars()
}
}
-void LLVOWLSky::buildFanBuffer(LLStrider<LLVector3> & vertices,
- LLStrider<LLVector2> & texCoords,
- LLStrider<U16> & indices)
-{
- const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius();
-
- U32 i, num_slices;
- F32 phi0, theta, x0, y0, z0;
-
- // paranoia checking for SL-55986/SL-55833
- U32 count_verts = 0;
- U32 count_indices = 0;
-
- // apex
- *vertices++ = LLVector3(0.f, RADIUS, 0.f);
- *texCoords++ = LLVector2(0.5f, 0.5f);
- ++count_verts;
-
- num_slices = getNumSlices();
-
- // and fan in a circle around the apex
- phi0 = calcPhi(1);
- for(i = 0; i < num_slices; ++i) {
- theta = 2.f * F_PI * float(i) / float(num_slices);
-
- // standard transformation from spherical to
- // rectangular coordinates
- x0 = sin(phi0) * cos(theta);
- y0 = cos(phi0);
- z0 = sin(phi0) * sin(theta);
-
- *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
- // generate planar uv coordinates
- // note: x and z are transposed in order for things to animate
- // correctly in the global coordinate system where +x is east and
- // +y is north
- *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
- ++count_verts;
-
- if (i > 0)
- {
- *indices++ = 0;
- *indices++ = i;
- *indices++ = i+1;
- count_indices += 3;
- }
- }
-
- // the last vertex of the last triangle should wrap around to
- // the beginning
- *indices++ = 0;
- *indices++ = num_slices;
- *indices++ = 1;
- count_indices += 3;
-
- // paranoia checking for SL-55986/SL-55833
- llassert(getFanNumVerts() == count_verts);
- llassert(getFanNumIndices() == count_indices);
-}
-
-void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
+void LLVOWLSky::buildStripsBuffer(U32 begin_stack,
+ U32 end_stack,
+ U32& vertex_count,
+ U32& index_count,
LLStrider<LLVector3> & vertices,
LLStrider<LLVector2> & texCoords,
LLStrider<U16> & indices)
{
- const F32 RADIUS = LLWLParamManager::getInstance()->getDomeRadius();
+ const F32 RADIUS = LLEnvironment::instance().getCurrentSky()->getDomeRadius();
U32 i, j, num_slices, num_stacks;
F32 phi0, theta, x0, y0, z0;
@@ -661,7 +387,11 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
llassert(end_stack <= num_stacks);
// stacks are iterated one-indexed since phi(0) was handled by the fan above
- for(i = begin_stack + 1; i <= end_stack+1; ++i)
+#if NEW_TESS
+ for(i = begin_stack; i <= end_stack; ++i)
+#else
+ for(i = begin_stack + 1; i <= end_stack+1; ++i)
+#endif
{
phi0 = calcPhi(i);
@@ -675,7 +405,10 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
y0 = cos(phi0);
z0 = sin(phi0) * sin(theta);
- if (i == num_stacks-2)
+#if NEW_TESS
+ *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
+#else
+ if (i == num_stacks-2)
{
*vertices++ = LLVector3(x0*RADIUS, y0*RADIUS-1024.f*2.f, z0*RADIUS);
}
@@ -687,6 +420,8 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
{
*vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
}
+#endif
+
++count_verts;
// generate planar uv coordinates
@@ -725,6 +460,9 @@ void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
*indices++ = i * num_slices + k ;
count_indices++ ;
}
+
+ vertex_count = count_verts;
+ index_count = count_indices;
}
void LLVOWLSky::updateStarColors()
@@ -819,7 +557,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
LLVector3 left = at%LLVector3(0,0,1);
LLVector3 up = at%left;
- F32 sc = 0.5f+ll_frand()*1.25f;
+ F32 sc = 16.0f + (ll_frand() * 20.0f);
left *= sc;
up *= sc;
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 1d419b5fea..2b7ebe75dd 100644
--- a/indra/newview/llvowlsky.h
+++ b/indra/newview/llvowlsky.h
@@ -31,17 +31,8 @@
class LLVOWLSky : public LLStaticViewerObject {
private:
- static const F32 DISTANCE_TO_STARS;
-
- // anything less than 3 makes it impossible to create a closed dome.
- static const U32 MIN_SKY_DETAIL;
- // anything bigger than about 180 will cause getStripsNumVerts() to exceed 65535.
- static const U32 MAX_SKY_DETAIL;
-
inline static U32 getNumStacks(void);
inline static U32 getNumSlices(void);
- inline static U32 getFanNumVerts(void);
- inline static U32 getFanNumIndices(void);
inline static U32 getStripsNumVerts(void);
inline static U32 getStripsNumIndices(void);
inline static U32 getStarsNumVerts(void);
@@ -50,9 +41,6 @@ private:
public:
LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- void initSunDirection(LLVector3 const & sun_direction,
- LLVector3 const & sun_angular_velocity);
-
/*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
/*virtual*/ BOOL isActive(void) const;
/*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline);
@@ -60,6 +48,7 @@ public:
void drawStars(void);
void drawDome(void);
+ void drawFsSky(void); // fullscreen sky for advanced atmo
void resetVertexBuffers(void);
void cleanupGL();
@@ -72,16 +61,13 @@ private:
// helper function for initializing the stars.
void initStars();
- // helper function for building the fan vertex buffer.
- static void buildFanBuffer(LLStrider<LLVector3> & vertices,
- LLStrider<LLVector2> & texCoords,
- LLStrider<U16> & indices);
-
// helper function for building the strips vertex buffer.
// note begin_stack and end_stack follow stl iterator conventions,
// begin_stack is the first stack to be included, end_stack is the first
// stack not to be included.
static void buildStripsBuffer(U32 begin_stack, U32 end_stack,
+ U32& vertex_count,
+ U32& index_count,
LLStrider<LLVector3> & vertices,
LLStrider<LLVector2> & texCoords,
LLStrider<U16> & indices);
@@ -93,7 +79,7 @@ private:
BOOL updateStarGeometry(LLDrawable *drawable);
private:
- LLPointer<LLVertexBuffer> mFanVerts;
+ LLPointer<LLVertexBuffer> mFsSkyVerts;
std::vector< LLPointer<LLVertexBuffer> > mStripsVerts;
LLPointer<LLVertexBuffer> mStarsVerts;
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index dd6c77ca7d..6273f10c69 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -91,7 +91,11 @@ void LLWatchdogEntry::start()
void LLWatchdogEntry::stop()
{
- LLWatchdog::getInstance()->remove(this);
+ // this can happen very late in the shutdown sequence
+ if (! LLWatchdog::wasDeleted())
+ {
+ LLWatchdog::getInstance()->remove(this);
+ }
}
// LLWatchdogTimeout
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
deleted file mode 100644
index b484b6d709..0000000000
--- a/indra/newview/llwaterparammanager.cpp
+++ /dev/null
@@ -1,442 +0,0 @@
-/**
- * @file llwaterparammanager.cpp
- * @brief Implementation for the LLWaterParamManager class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llwaterparammanager.h"
-
-#include "llrender.h"
-
-#include "pipeline.h"
-#include "llsky.h"
-
-#include "lldiriterator.h"
-#include "llfloaterreg.h"
-#include "llsliderctrl.h"
-#include "llspinctrl.h"
-#include "llcheckboxctrl.h"
-#include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llviewercamera.h"
-#include "llcombobox.h"
-#include "lllineeditor.h"
-#include "llsdserialize.h"
-
-#include "v4math.h"
-#include "llviewercontrol.h"
-#include "lldrawpoolwater.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llviewerregion.h"
-
-#include "llwlparammanager.h"
-#include "llwaterparamset.h"
-
-#include "curl/curl.h"
-
-LLWaterParamManager::LLWaterParamManager() :
- mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"),
- mFogDensity(4, "waterFogDensity", 2),
- mUnderWaterFogMod(0.25, "underWaterFogMod"),
- mNormalScale(2.f, 2.f, 2.f, "normScale"),
- mFresnelScale(0.5f, "fresnelScale"),
- mFresnelOffset(0.4f, "fresnelOffset"),
- mScaleAbove(0.025f, "scaleAbove"),
- mScaleBelow(0.2f, "scaleBelow"),
- mBlurMultiplier(0.1f, "blurMultiplier"),
- mWave1Dir(.5f, .5f, "wave1Dir"),
- mWave2Dir(.5f, .5f, "wave2Dir"),
- mDensitySliderValue(1.0f),
- mWaterFogKS(1.0f)
-{
-}
-
-LLWaterParamManager::~LLWaterParamManager()
-{
-}
-
-void LLWaterParamManager::loadAllPresets()
-{
- // First, load system (coming out of the box) water presets.
- loadPresetsFromDir(getSysDir());
-
- // Then load user presets. Note that user day presets will modify any system ones already loaded.
- loadPresetsFromDir(getUserDir());
-}
-
-void LLWaterParamManager::loadPresetsFromDir(const std::string& dir)
-{
- LL_DEBUGS("AppInit", "Shaders") << "Loading water presets from " << dir << LL_ENDL;
-
- LLDirIterator dir_iter(dir, "*.xml");
- while (1)
- {
- std::string file;
- if (!dir_iter.next(file))
- {
- break; // no more files
- }
-
- std::string path = gDirUtilp->add(dir, file);
- if (!loadPreset(path))
- {
- LL_WARNS() << "Error loading water preset from " << path << LL_ENDL;
- }
- }
-}
-
-bool LLWaterParamManager::loadPreset(const std::string& path)
-{
- llifstream xml_file;
- std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
-
- xml_file.open(path.c_str());
- if (!xml_file)
- {
- return false;
- }
-
- LL_DEBUGS("AppInit", "Shaders") << "Loading water " << name << LL_ENDL;
-
- LLSD params_data;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED);
- xml_file.close();
-
- if (hasParamSet(name))
- {
- setParamSet(name, params_data);
- }
- else
- {
- addParamSet(name, params_data);
- }
-
- return true;
-}
-
-void LLWaterParamManager::savePreset(const std::string & name)
-{
- llassert(!name.empty());
-
- // make an empty llsd
- LLSD paramsData(LLSD::emptyMap());
- std::string pathName(getUserDir() + LLURI::escape(name) + ".xml");
-
- // fill it with LLSD windlight params
- paramsData = mParamList[name].getAll();
-
- // write to file
- llofstream presetsXML(pathName.c_str());
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
- presetsXML.close();
-
- propagateParameters();
-}
-
-void LLWaterParamManager::propagateParameters(void)
-{
- // bind the variables only if we're using shaders
- if(gPipeline.canUseVertexShaders())
- {
- LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
- end_shaders = LLViewerShaderMgr::instance()->endShaders();
- for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
- {
- if (shaders_iter->mProgramObject != 0
- && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)
- {
- shaders_iter->mUniformsDirty = TRUE;
- }
- }
- }
-
- bool err;
- F32 fog_density_slider =
- log(mCurParams.getFloat(mFogDensity.mName, err)) /
- log(mFogDensity.mBase);
-
- setDensitySliderValue(fog_density_slider);
-}
-
-void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
-{
- if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
- {
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV);
-shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV);
- shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV);
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity());
- shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS);
- shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);
- }
-}
-
-void LLWaterParamManager::applyParams(const LLSD& params, bool interpolate)
-{
- if (params.size() == 0)
- {
- LL_WARNS() << "Undefined water params" << LL_ENDL;
- return;
- }
-
- if (interpolate)
- {
- LLWLParamManager::getInstance()->mAnimator.startInterpolation(params);
- }
- else
- {
- mCurParams.setAll(params);
- }
-}
-
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERPARAM("Update Water Params");
-
-void LLWaterParamManager::update(LLViewerCamera * cam)
-{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_WATERPARAM);
-
- // update the shaders and the menu
- propagateParameters();
-
- // only do this if we're dealing with shaders
- if(gPipeline.canUseVertexShaders())
- {
- //transform water plane to eye space
- glh::vec3f norm(0.f, 0.f, 1.f);
- glh::vec3f p(0.f, 0.f, gAgent.getRegion()->getWaterHeight()+0.1f);
-
- F32 modelView[16];
- for (U32 i = 0; i < 16; i++)
- {
- modelView[i] = (F32) gGLModelView[i];
- }
-
- glh::matrix4f mat(modelView);
- glh::matrix4f invtrans = mat.inverse().transpose();
- glh::vec3f enorm;
- glh::vec3f ep;
- invtrans.mult_matrix_vec(norm, enorm);
- enorm.normalize();
- mat.mult_matrix_vec(p, ep);
-
- mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
-
- LLVector3 sunMoonDir;
- if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
- {
- sunMoonDir = gSky.getSunDirection();
- }
- else
- {
- sunMoonDir = gSky.getMoonDirection();
- }
- sunMoonDir.normVec();
- mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP);
-
- LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
- end_shaders = LLViewerShaderMgr::instance()->endShaders();
- for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
- {
- if (shaders_iter->mProgramObject != 0
- && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)
- {
- shaders_iter->mUniformsDirty = TRUE;
- }
- }
- }
-}
-
-bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param)
-{
- // add a new one if not one there already
- preset_map_t::iterator mIt = mParamList.find(name);
- if(mIt == mParamList.end())
- {
- mParamList[name] = param;
- mPresetListChangeSignal();
- return true;
- }
-
- return false;
-}
-
-BOOL LLWaterParamManager::addParamSet(const std::string& name, LLSD const & param)
-{
- LLWaterParamSet param_set;
- param_set.setAll(param);
- return addParamSet(name, param_set);
-}
-
-bool LLWaterParamManager::getParamSet(const std::string& name, LLWaterParamSet& param)
-{
- // find it and set it
- preset_map_t::iterator mIt = mParamList.find(name);
- if(mIt != mParamList.end())
- {
- param = mParamList[name];
- param.mName = name;
- return true;
- }
-
- return false;
-}
-
-bool LLWaterParamManager::hasParamSet(const std::string& name)
-{
- LLWaterParamSet dummy;
- return getParamSet(name, dummy);
-}
-
-bool LLWaterParamManager::setParamSet(const std::string& name, LLWaterParamSet& param)
-{
- mParamList[name] = param;
-
- return true;
-}
-
-bool LLWaterParamManager::setParamSet(const std::string& name, const LLSD & param)
-{
- // quick, non robust (we won't be working with files, but assets) check
- if(!param.isMap())
- {
- return false;
- }
-
- mParamList[name].setAll(param);
-
- return true;
-}
-
-bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_from_disk)
-{
- // remove from param list
- preset_map_t::iterator it = mParamList.find(name);
- if (it == mParamList.end())
- {
- LL_WARNS("WindLight") << "No water preset named " << name << LL_ENDL;
- return false;
- }
-
- mParamList.erase(it);
-
- // remove from file system if requested
- if (delete_from_disk)
- {
- if (gDirUtilp->deleteFilesInDir(getUserDir(), LLURI::escape(name) + ".xml") < 1)
- {
- LL_WARNS("WindLight") << "Error removing water preset " << name << " from disk" << LL_ENDL;
- }
- }
-
- // signal interested parties
- mPresetListChangeSignal();
- return true;
-}
-
-bool LLWaterParamManager::isSystemPreset(const std::string& preset_name) const
-{
- // *TODO: file system access is excessive here.
- return gDirUtilp->fileExists(getSysDir() + LLURI::escape(preset_name) + ".xml");
-}
-
-void LLWaterParamManager::getPresetNames(preset_name_list_t& presets) const
-{
- presets.clear();
-
- for (preset_map_t::const_iterator it = mParamList.begin(); it != mParamList.end(); ++it)
- {
- presets.push_back(it->first);
- }
-}
-
-void LLWaterParamManager::getPresetNames(preset_name_list_t& user_presets, preset_name_list_t& system_presets) const
-{
- user_presets.clear();
- system_presets.clear();
-
- for (preset_map_t::const_iterator it = mParamList.begin(); it != mParamList.end(); ++it)
- {
- if (isSystemPreset(it->first))
- {
- system_presets.push_back(it->first);
- }
- else
- {
- user_presets.push_back(it->first);
- }
- }
-}
-
-void LLWaterParamManager::getUserPresetNames(preset_name_list_t& user_presets) const
-{
- preset_name_list_t dummy;
- getPresetNames(user_presets, dummy);
-}
-
-boost::signals2::connection LLWaterParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
-{
- return mPresetListChangeSignal.connect(cb);
-}
-
-F32 LLWaterParamManager::getFogDensity(void)
-{
- bool err;
-
- F32 fogDensity = mCurParams.getFloat("waterFogDensity", err);
-
- // modify if we're underwater
- const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
- F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
- if(camera_height <= water_height)
- {
- // raise it to the underwater fog density modifier
- fogDensity = pow(fogDensity, mCurParams.getFloat("underWaterFogMod", err));
- }
-
- return fogDensity;
-}
-
-// virtual static
-void LLWaterParamManager::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Initializing water" << LL_ENDL;
- loadAllPresets();
-}
-
-// static
-std::string LLWaterParamManager::getSysDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "");
-}
-
-// static
-std::string LLWaterParamManager::getUserDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/water", "");
-}
diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h
deleted file mode 100644
index 3f169e439a..0000000000
--- a/indra/newview/llwaterparammanager.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/**
- * @file llwaterparammanager.h
- * @brief Implementation for the LLWaterParamManager class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_WATER_PARAMMANAGER_H
-#define LL_WATER_PARAMMANAGER_H
-
-#include <list>
-#include <map>
-#include "llwaterparamset.h"
-#include "llviewercamera.h"
-#include "v4color.h"
-
-const F32 WATER_FOG_LIGHT_CLAMP = 0.3f;
-
-// color control
-struct WaterColorControl {
-
- F32 mR, mG, mB, mA, mI; /// the values
- std::string mName; /// name to use to dereference params
- std::string mSliderName; /// name of the slider in menu
- bool mHasSliderName; /// only set slider name for true color types
-
- inline WaterColorControl(F32 red, F32 green, F32 blue, F32 alpha,
- F32 intensity, const std::string& n, const std::string& sliderName = LLStringUtil::null)
- : mR(red), mG(green), mB(blue), mA(alpha), mI(intensity), mName(n), mSliderName(sliderName)
- {
- // if there's a slider name, say we have one
- mHasSliderName = false;
- if (mSliderName != "") {
- mHasSliderName = true;
- }
- }
-
- inline WaterColorControl & operator = (LLColor4 const & val)
- {
- mR = val.mV[0];
- mG = val.mV[1];
- mB = val.mV[2];
- mA = val.mV[3];
- return *this;
- }
-
- inline operator LLColor4 (void) const
- {
- return LLColor4(mR, mG, mB, mA);
- }
-
- inline WaterColorControl & operator = (LLVector4 const & val)
- {
- mR = val.mV[0];
- mG = val.mV[1];
- mB = val.mV[2];
- mA = val.mV[3];
- return *this;
- }
-
- inline operator LLVector4 (void) const
- {
- return LLVector4(mR, mG, mB, mA);
- }
-
- inline operator LLVector3 (void) const
- {
- return LLVector3(mR, mG, mB);
- }
-
- inline void update(LLWaterParamSet & params) const
- {
- params.set(mName, mR, mG, mB, mA);
- }
-};
-
-struct WaterVector3Control
-{
- F32 mX;
- F32 mY;
- F32 mZ;
-
- std::string mName;
-
- // basic constructor
- inline WaterVector3Control(F32 valX, F32 valY, F32 valZ, const std::string& n)
- : mX(valX), mY(valY), mZ(valZ), mName(n)
- {
- }
-
- inline WaterVector3Control & operator = (LLVector3 const & val)
- {
- mX = val.mV[0];
- mY = val.mV[1];
- mZ = val.mV[2];
-
- return *this;
- }
-
- inline void update(LLWaterParamSet & params) const
- {
- params.set(mName, mX, mY, mZ);
- }
-
-};
-
-struct WaterVector2Control
-{
- F32 mX;
- F32 mY;
-
- std::string mName;
-
- // basic constructor
- inline WaterVector2Control(F32 valX, F32 valY, const std::string& n)
- : mX(valX), mY(valY), mName(n)
- {
- }
-
- inline WaterVector2Control & operator = (LLVector2 const & val)
- {
- mX = val.mV[0];
- mY = val.mV[1];
-
- return *this;
- }
-
- inline void update(LLWaterParamSet & params) const
- {
- params.set(mName, mX, mY);
- }
-};
-
-// float slider control
-struct WaterFloatControl
-{
- F32 mX;
- std::string mName;
- F32 mMult;
-
- inline WaterFloatControl(F32 val, const std::string& n, F32 m=1.0f)
- : mX(val), mName(n), mMult(m)
- {
- }
-
- inline WaterFloatControl & operator = (LLVector4 const & val)
- {
- mX = val.mV[0];
-
- return *this;
- }
-
- inline operator F32 (void) const
- {
- return mX;
- }
-
- inline void update(LLWaterParamSet & params) const
- {
- params.set(mName, mX);
- }
-};
-
-// float slider control
-struct WaterExpFloatControl
-{
- F32 mExp;
- std::string mName;
- F32 mBase;
-
- inline WaterExpFloatControl(F32 val, const std::string& n, F32 b)
- : mExp(val), mName(n), mBase(b)
- {
- }
-
- inline WaterExpFloatControl & operator = (F32 val)
- {
- mExp = log(val) / log(mBase);
-
- return *this;
- }
-
- inline operator F32 (void) const
- {
- return pow(mBase, mExp);
- }
-
- inline void update(LLWaterParamSet & params) const
- {
- params.set(mName, pow(mBase, mExp));
- }
-};
-
-
-/// WindLight parameter manager class - what controls all the wind light shaders
-class LLWaterParamManager : public LLSingleton<LLWaterParamManager>
-{
- LLSINGLETON(LLWaterParamManager);
- ~LLWaterParamManager();
- LOG_CLASS(LLWaterParamManager);
-public:
- typedef std::list<std::string> preset_name_list_t;
- typedef std::map<std::string, LLWaterParamSet> preset_map_t;
- typedef boost::signals2::signal<void()> preset_list_signal_t;
-
- /// save the parameter presets to file
- void savePreset(const std::string & name);
-
- /// send the parameters to the shaders
- void propagateParameters(void);
-
- // display specified water
- void applyParams(const LLSD& params, bool interpolate);
-
- /// update information for the shader
- void update(LLViewerCamera * cam);
-
- /// Update shader uniforms that have changed.
- void updateShaderUniforms(LLGLSLShader * shader);
-
- /// add a param to the list
- bool addParamSet(const std::string& name, LLWaterParamSet& param);
-
- /// add a param to the list
- BOOL addParamSet(const std::string& name, LLSD const & param);
-
- /// get a param from the list
- bool getParamSet(const std::string& name, LLWaterParamSet& param);
-
- /// check whether the preset is in the list
- bool hasParamSet(const std::string& name);
-
- /// set the param in the list with a new param
- bool setParamSet(const std::string& name, LLWaterParamSet& param);
-
- /// set the param in the list with a new param
- bool setParamSet(const std::string& name, LLSD const & param);
-
- /// gets rid of a parameter and any references to it
- /// returns true if successful
- bool removeParamSet(const std::string& name, bool delete_from_disk);
-
- /// @return true if the preset comes out of the box
- bool isSystemPreset(const std::string& preset_name) const;
-
- /// @return all named water presets.
- const preset_map_t& getPresets() const { return mParamList; }
-
- /// @return user and system preset names as a single list
- void getPresetNames(preset_name_list_t& presets) const;
-
- /// @return user and system preset names separately
- void getPresetNames(preset_name_list_t& user_presets, preset_name_list_t& system_presets) const;
-
- /// @return list of user presets names
- void getUserPresetNames(preset_name_list_t& user_presets) const;
-
- /// Emitted when a preset gets added or deleted.
- boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
-
- /// set the normap map we want for water
- bool setNormalMapID(const LLUUID& img);
-
- void setDensitySliderValue(F32 val);
-
- /// getters for all the different things water param manager maintains
- LLUUID getNormalMapID(void);
- LLVector2 getWave1Dir(void);
- LLVector2 getWave2Dir(void);
- F32 getScaleAbove(void);
- F32 getScaleBelow(void);
- LLVector3 getNormalScale(void);
- F32 getFresnelScale(void);
- F32 getFresnelOffset(void);
- F32 getBlurMultiplier(void);
- F32 getFogDensity(void);
- LLColor4 getFogColor(void);
-
-public:
-
- LLWaterParamSet mCurParams;
-
- /// Atmospherics
- WaterColorControl mFogColor;
- WaterExpFloatControl mFogDensity;
- WaterFloatControl mUnderWaterFogMod;
-
- /// wavelet scales and directions
- WaterVector3Control mNormalScale;
- WaterVector2Control mWave1Dir;
- WaterVector2Control mWave2Dir;
-
- // controls how water is reflected and refracted
- WaterFloatControl mFresnelScale;
- WaterFloatControl mFresnelOffset;
- WaterFloatControl mScaleAbove;
- WaterFloatControl mScaleBelow;
- WaterFloatControl mBlurMultiplier;
-
- F32 mDensitySliderValue;
-
-private:
- /*virtual*/ void initSingleton();
- void loadAllPresets();
- void loadPresetsFromDir(const std::string& dir);
- bool loadPreset(const std::string& path);
-
- static std::string getSysDir();
- static std::string getUserDir();
-
- LLVector4 mWaterPlane;
- F32 mWaterFogKS;
-
- // list of all the parameters, listed by name
- preset_map_t mParamList;
-
- preset_list_signal_t mPresetListChangeSignal;
-};
-
-inline void LLWaterParamManager::setDensitySliderValue(F32 val)
-{
- val /= 10.0f;
- val = 1.0f - val;
- val *= val * val;
-// val *= val;
- mDensitySliderValue = val;
-}
-
-inline LLUUID LLWaterParamManager::getNormalMapID()
-{
- return mCurParams.mParamValues["normalMap"].asUUID();
-}
-
-inline bool LLWaterParamManager::setNormalMapID(const LLUUID& id)
-{
- mCurParams.mParamValues["normalMap"] = id;
- return true;
-}
-
-inline LLVector2 LLWaterParamManager::getWave1Dir(void)
-{
- bool err;
- return mCurParams.getVector2("wave1Dir", err);
-}
-
-inline LLVector2 LLWaterParamManager::getWave2Dir(void)
-{
- bool err;
- return mCurParams.getVector2("wave2Dir", err);
-}
-
-inline F32 LLWaterParamManager::getScaleAbove(void)
-{
- bool err;
- return mCurParams.getFloat("scaleAbove", err);
-}
-
-inline F32 LLWaterParamManager::getScaleBelow(void)
-{
- bool err;
- return mCurParams.getFloat("scaleBelow", err);
-}
-
-inline LLVector3 LLWaterParamManager::getNormalScale(void)
-{
- bool err;
- return mCurParams.getVector3("normScale", err);
-}
-
-inline F32 LLWaterParamManager::getFresnelScale(void)
-{
- bool err;
- return mCurParams.getFloat("fresnelScale", err);
-}
-
-inline F32 LLWaterParamManager::getFresnelOffset(void)
-{
- bool err;
- return mCurParams.getFloat("fresnelOffset", err);
-}
-
-inline F32 LLWaterParamManager::getBlurMultiplier(void)
-{
- bool err;
- return mCurParams.getFloat("blurMultiplier", err);
-}
-
-inline LLColor4 LLWaterParamManager::getFogColor(void)
-{
- bool err;
- return LLColor4(mCurParams.getVector4("waterFogColor", err));
-}
-
-#endif
diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
deleted file mode 100644
index 9cc91d2246..0000000000
--- a/indra/newview/llwaterparamset.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * @file llwaterparamset.cpp
- * @brief Implementation for the LLWaterParamSet class.
- *
- * $LicenseInfo:firstyear=2005&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 "llwaterparamset.h"
-#include "llsd.h"
-
-#include "llwaterparammanager.h"
-#include "lluictrlfactory.h"
-#include "llsliderctrl.h"
-#include "llviewertexturelist.h"
-#include "llviewercontrol.h"
-#include "lluuid.h"
-
-#include <llgl.h>
-
-#include <sstream>
-
-LLWaterParamSet::LLWaterParamSet(void) :
- mName("Unnamed Preset")
-{
- LLSD vec4;
- LLSD vec3;
- LLSD real(0.0f);
-
- vec4 = LLSD::emptyArray();
- vec4.append(22.f/255.f);
- vec4.append(43.f/255.f);
- vec4.append(54.f/255.f);
- vec4.append(0.f/255.f);
-
- vec3 = LLSD::emptyArray();
- vec3.append(2);
- vec3.append(2);
- vec3.append(2);
-
- LLSD wave1, wave2;
- wave1 = LLSD::emptyArray();
- wave2 = LLSD::emptyArray();
- wave1.append(0.5f);
- wave1.append(-.17f);
- wave2.append(0.58f);
- wave2.append(-.67f);
-
- mParamValues.insert("waterFogColor", vec4);
- mParamValues.insert("waterFogDensity", 16.0f);
- mParamValues.insert("underWaterFogMod", 0.25f);
- mParamValues.insert("normScale", vec3);
- mParamValues.insert("fresnelScale", 0.5f);
- mParamValues.insert("fresnelOffset", 0.4f);
- mParamValues.insert("scaleAbove", 0.025f);
- mParamValues.insert("scaleBelow", 0.2f);
- mParamValues.insert("blurMultiplier", 0.01f);
- mParamValues.insert("wave1Dir", wave1);
- mParamValues.insert("wave2Dir", wave2);
- mParamValues.insert("normalMap", DEFAULT_WATER_NORMAL);
-
-}
-
-void LLWaterParamSet::set(const std::string& paramName, float x)
-{
- // handle case where no array
- if(mParamValues[paramName].isReal())
- {
- mParamValues[paramName] = x;
- }
-
- // handle array
- else if(mParamValues[paramName].isArray() &&
- mParamValues[paramName][0].isReal())
- {
- mParamValues[paramName][0] = x;
- }
-}
-
-void LLWaterParamSet::set(const std::string& paramName, float x, float y) {
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
-}
-
-void LLWaterParamSet::set(const std::string& paramName, float x, float y, float z)
-{
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
- mParamValues[paramName][2] = z;
-}
-
-void LLWaterParamSet::set(const std::string& paramName, float x, float y, float z, float w)
-{
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
- mParamValues[paramName][2] = z;
- mParamValues[paramName][3] = w;
-}
-
-void LLWaterParamSet::set(const std::string& paramName, const float * val)
-{
- mParamValues[paramName][0] = val[0];
- mParamValues[paramName][1] = val[1];
- mParamValues[paramName][2] = val[2];
- mParamValues[paramName][3] = val[3];
-}
-
-void LLWaterParamSet::set(const std::string& paramName, const LLVector4 & val)
-{
- mParamValues[paramName][0] = val.mV[0];
- mParamValues[paramName][1] = val.mV[1];
- mParamValues[paramName][2] = val.mV[2];
- mParamValues[paramName][3] = val.mV[3];
-}
-
-void LLWaterParamSet::set(const std::string& paramName, const LLColor4 & val)
-{
- mParamValues[paramName][0] = val.mV[0];
- mParamValues[paramName][1] = val.mV[1];
- mParamValues[paramName][2] = val.mV[2];
- mParamValues[paramName][3] = val.mV[3];
-}
-
-LLVector4 LLWaterParamSet::getVector4(const std::string& paramName, bool& error)
-{
-
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (!cur_val.isArray() || cur_val.size() != 4)
- {
- error = true;
- return LLVector4(0,0,0,0);
- }
-
- LLVector4 val;
- val.mV[0] = (F32) cur_val[0].asReal();
- val.mV[1] = (F32) cur_val[1].asReal();
- val.mV[2] = (F32) cur_val[2].asReal();
- val.mV[3] = (F32) cur_val[3].asReal();
-
- error = false;
- return val;
-}
-
-LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error)
-{
-
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (!cur_val.isArray()|| cur_val.size() != 3)
- {
- error = true;
- return LLVector3(0,0,0);
- }
-
- LLVector3 val;
- val.mV[0] = (F32) cur_val[0].asReal();
- val.mV[1] = (F32) cur_val[1].asReal();
- val.mV[2] = (F32) cur_val[2].asReal();
-
- error = false;
- return val;
-}
-
-LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error)
-{
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (!cur_val.isArray() || cur_val.size() != 2)
- {
- error = true;
- return LLVector2(0,0);
- }
-
- LLVector2 val;
- val.mV[0] = (F32) cur_val[0].asReal();
- val.mV[1] = (F32) cur_val[1].asReal();
-
- error = false;
- return val;
-}
-
-F32 LLWaterParamSet::getFloat(const std::string& paramName, bool& error)
-{
-
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (cur_val.isArray() && cur_val.size() != 0)
- {
- error = false;
- return (F32) cur_val[0].asReal();
- }
-
- if(cur_val.isReal())
- {
- error = false;
- return (F32) cur_val.asReal();
- }
-
- error = true;
- return 0;
-}
-
-// Added for interpolation effect in DEV-33645
-// Based on LLWLParamSet::mix, but written by Jacob without an intimate knowledge of how WindLight works.
-// The function definition existed in the header but was never implemented. If you think there is something
-// wrong with this, you're probably right. Ask Jacob, Q, or a member of the original WindLight team.
-void LLWaterParamSet::mix(LLWaterParamSet& src, LLWaterParamSet& dest, F32 weight)
-{
- // Setup
- LLSD srcVal, destVal; // LLSD holders for get/set calls, reusable
-
- // Iterate through values
- for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
- {
- // If param exists in both src and dest, set the holder variables, otherwise skip
- if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
- {
- srcVal = src.mParamValues[iter->first];
- destVal = dest.mParamValues[iter->first];
- }
- else
- {
- continue;
- }
-
- if(iter->second.isReal()) // If it's a real, interpolate directly
- {
- iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
- }
- else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those
- && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
- {
- // Actually do interpolation: old value + (difference in values * factor)
- for(int i=0; i < iter->second.size(); ++i)
- {
- // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation
- iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
- }
- }
- else // Else, skip
- {
- continue;
- }
- }
-}
diff --git a/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h
deleted file mode 100644
index 368cb0ccba..0000000000
--- a/indra/newview/llwaterparamset.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file llwlparamset.h
- * @brief Interface for the LLWaterParamSet class.
- *
- * $LicenseInfo:firstyear=2005&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_WATER_PARAM_SET_H
-#define LL_WATER_PARAM_SET_H
-
-#include <string>
-#include <map>
-
-#include "v4math.h"
-#include "v4color.h"
-#include "llviewershadermgr.h"
-#include "llstringtable.h"
-
-class LLWaterParamSet;
-
-/// A class representing a set of parameter values for the Water shaders.
-class LLWaterParamSet
-{
- friend class LLWaterParamManager;
-
-public:
- std::string mName;
-
-private:
-
- LLSD mParamValues;
- std::vector<LLStaticHashedString> mParamHashedNames;
-
- void updateHashedNames();
-
-public:
-
- LLWaterParamSet();
-
- /// Bind this set of parameter values to the uniforms of a particular shader.
- void update(LLGLSLShader * shader) const;
-
- /// set the total llsd
- void setAll(const LLSD& val);
-
- /// get the total llsd
- const LLSD& getAll();
-
- /// Set a float parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The float value to set.
- void set(const std::string& paramName, float x);
-
- /// Set a float2 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- void set(const std::string& paramName, float x, float y);
-
- /// Set a float3 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- /// \param z The z component's value to set.
- void set(const std::string& paramName, float x, float y, float z);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- /// \param z The z component's value to set.
- /// \param w The w component's value to set.
- void set(const std::string& paramName, float x, float y, float z, float w);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val An array of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const float * val);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val A struct of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const LLVector4 & val);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val A struct of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const LLColor4 & val);
-
- /// Get a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- LLVector4 getVector4(const std::string& paramName, bool& error);
-
- /// Get a float3 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- LLVector3 getVector3(const std::string& paramName, bool& error);
-
- /// Get a float2 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- LLVector2 getVector2(const std::string& paramName, bool& error);
-
- /// Get an integer parameter
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- F32 getFloat(const std::string& paramName, bool& error);
-
- /// interpolate two parameter sets
- /// \param src The parameter set to start with
- /// \param dest The parameter set to end with
- /// \param weight The amount to interpolate
- void mix(LLWaterParamSet& src, LLWaterParamSet& dest,
- F32 weight);
-
-};
-
-inline void LLWaterParamSet::setAll(const LLSD& val)
-{
- if(val.isMap()) {
- LLSD::map_const_iterator mIt = val.beginMap();
- for(; mIt != val.endMap(); mIt++)
- {
- mParamValues[mIt->first] = mIt->second;
- }
- }
- updateHashedNames();
-}
-
-inline void LLWaterParamSet::updateHashedNames()
-{
- mParamHashedNames.clear();
- // Iterate through values
- for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
- {
- mParamHashedNames.push_back(LLStaticHashedString(iter->first));
- }
-}
-
-inline const LLSD& LLWaterParamSet::getAll()
-{
- return mParamValues;
-}
-
-#endif // LL_WaterPARAM_SET_H
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index e7bbee5efd..9acc0f8d2f 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -38,6 +38,7 @@
#include "llgesturemgr.h"
#include "lltransutil.h"
#include "llviewerattachmenu.h"
+#include "llviewermenu.h"
#include "llvoavatarself.h"
class LLFindOutfitItems : public LLInventoryCollectFunctor
@@ -639,6 +640,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
: LLInventoryItemsList(p)
{
setSortOrder(E_SORT_BY_TYPE_LAYER, false);
+ mMenuWearableType = LLWearableType::WT_NONE;
mIsStandalone = p.standalone;
if (mIsStandalone)
{
@@ -730,10 +732,15 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)
getSelectedUUIDs(selected_uuids);
if (selected_uuids.empty())
{
- return;
+ if ((mMenuWearableType != LLWearableType::WT_NONE) && (size() == 0))
+ {
+ ContextMenu::instance().show(this, mMenuWearableType, x, y);
+ }
+ }
+ else
+ {
+ ContextMenu::instance().show(this, selected_uuids, x, y);
}
-
- ContextMenu::instance().show(this, selected_uuids, x, y);
}
void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now)
@@ -784,6 +791,46 @@ void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, const uuid_ve
mParent = NULL; // to avoid dereferencing an invalid pointer
}
+void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y)
+{
+ mParent = dynamic_cast<LLWearableItemsList*>(spawning_view);
+ LLContextMenu* menup = mMenuHandle.get();
+ if (menup)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = menup->getParent();
+ if (parent)
+ {
+ parent->removeChild(menup);
+ }
+ delete menup;
+ mUUIDs.clear();
+ }
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Wearable.CreateNew", boost::bind(createNewWearableByType, w_type));
+ menup = createFromFile("menu_wearable_list_item.xml");
+ if (!menup)
+ {
+ LL_WARNS() << "Context menu creation failed" << LL_ENDL;
+ return;
+ }
+ setMenuItemVisible(menup, "create_new", true);
+ setMenuItemEnabled(menup, "create_new", true);
+ setMenuItemVisible(menup, "wearable_attach_to", false);
+ setMenuItemVisible(menup, "wearable_attach_to_hud", false);
+
+ std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type));
+ LLMenuItemGL* menu_item = menup->getChild<LLMenuItemGL>("create_new");
+ menu_item->setLabel(new_label);
+
+ mMenuHandle = menup->getHandle();
+ menup->show(x, y);
+ LLMenuGL::showPopup(spawning_view, menup, x, y);
+
+ mParent = NULL; // to avoid dereferencing an invalid pointer
+}
+
// virtual
LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
{
@@ -794,7 +841,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
// Register handlers common for all wearable types.
registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
- registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
+ registrar.add("Wearable.Edit", boost::bind(handle_item_edit, selected_id));
registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
registrar.add("Wearable.TakeOffDetach",
@@ -809,6 +856,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
// Register handlers for attachments.
registrar.add("Attachment.Detach",
boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
+ registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id));
registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
@@ -838,6 +886,7 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
U32 n_already_worn = 0; // number of items worn of same type as selected items
U32 n_links = 0; // number of links among the selected items
U32 n_editable = 0; // number of editable items among the selected ones
+ U32 n_touchable = 0; // number of touchable items among the selected ones
bool can_be_worn = true;
@@ -858,12 +907,17 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
const LLWearableType::EType wearable_type = item->getWearableType();
const bool is_link = item->getIsLinkType();
const bool is_worn = get_is_item_worn(id);
- const bool is_editable = gAgentWearables.isWearableModifiable(id);
+ const bool is_editable = get_is_item_editable(id);
+ const bool is_touchable = enable_attachment_touch(id);
const bool is_already_worn = gAgentWearables.selfHasWearable(wearable_type);
if (is_worn)
{
++n_worn;
}
+ if (is_touchable)
+ {
+ ++n_touchable;
+ }
if (is_editable)
{
++n_editable;
@@ -893,8 +947,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
setMenuItemEnabled(menu, "wear_add", LLAppearanceMgr::instance().canAddWearables(ids));
setMenuItemVisible(menu, "wear_replace", n_worn == 0 && n_already_worn != 0 && can_be_worn);
//visible only when one item selected and this item is worn
- setMenuItemVisible(menu, "edit", !standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1);
- setMenuItemEnabled(menu, "edit", n_editable == 1 && n_worn == 1 && n_items == 1);
+ setMenuItemVisible(menu, "touch", !standalone && mask == MASK_ATTACHMENT && n_worn == n_items);
+ setMenuItemEnabled(menu, "touch", n_touchable && n_worn == 1 && n_items == 1);
+ setMenuItemVisible(menu, "edit", !standalone && mask & (MASK_CLOTHING|MASK_BODYPART|MASK_ATTACHMENT) && n_worn == n_items);
+ setMenuItemEnabled(menu, "edit", n_editable && n_worn == 1 && n_items == 1);
setMenuItemVisible(menu, "create_new", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
setMenuItemEnabled(menu, "create_new", LLAppearanceMgr::instance().canAddWearables(ids));
setMenuItemVisible(menu, "show_original", !standalone);
@@ -1004,4 +1060,10 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
LLAgentWearables::createWearable(item->getWearableType(), true);
}
+// static
+void LLWearableItemsList::ContextMenu::createNewWearableByType(LLWearableType::EType type)
+{
+ LLAgentWearables::createWearable(type, true);
+}
+
// EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index f3182ed163..ba8488b237 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -415,6 +415,8 @@ public:
public:
/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
+ void show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y);
+
protected:
enum {
MASK_CLOTHING = 0x01,
@@ -431,6 +433,7 @@ public:
static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val);
static void updateMask(U32& mask, LLAssetType::EType at);
static void createNewWearable(const LLUUID& item_id);
+ static void createNewWearableByType(LLWearableType::EType type);
LLWearableItemsList* mParent;
};
@@ -469,6 +472,8 @@ public:
void setSortOrder(ESortOrder sort_order, bool sort_now = true);
+ void setMenuWearableType(LLWearableType::EType type) { mMenuWearableType = type; }
+
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLWearableItemsList::Params& p);
@@ -479,6 +484,8 @@ protected:
bool mWornIndicationEnabled;
ESortOrder mSortOrder;
+
+ LLWearableType::EType mMenuWearableType;
};
#endif //LL_LLWEARABLEITEMSLIST_H
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index a34c5826ed..63257d6543 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -157,12 +157,12 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
const LLSD &default_subs)
{
LLSD substitution = default_subs;
- substitution["VERSION"] = LLVersionInfo::getVersion();
- substitution["VERSION_MAJOR"] = LLVersionInfo::getMajor();
- substitution["VERSION_MINOR"] = LLVersionInfo::getMinor();
- substitution["VERSION_PATCH"] = LLVersionInfo::getPatch();
- substitution["VERSION_BUILD"] = LLVersionInfo::getBuild();
- substitution["CHANNEL"] = LLVersionInfo::getChannel();
+ substitution["VERSION"] = LLVersionInfo::instance().getVersion();
+ substitution["VERSION_MAJOR"] = LLVersionInfo::instance().getMajor();
+ substitution["VERSION_MINOR"] = LLVersionInfo::instance().getMinor();
+ substitution["VERSION_PATCH"] = LLVersionInfo::instance().getPatch();
+ substitution["VERSION_BUILD"] = LLVersionInfo::instance().getBuild();
+ substitution["CHANNEL"] = LLVersionInfo::instance().getChannel();
substitution["GRID"] = LLGridManager::getInstance()->getGridId();
substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridId());
substitution["OS"] = LLOSInfo::instance().getOSStringSimple();
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index 7e5818ba1c..524adba652 100644
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
@@ -29,7 +29,11 @@
#include "stdtypes.h"
#include "llwin32headerslean.h"
+
+#pragma warning (push)
+#pragma warning (disable:4091) // a microsoft header has warnings. Very nice.
#include <dbghelp.h>
+#pragma warning (pop)
class LLWinDebug:
public LLSingleton<LLWinDebug>
diff --git a/indra/newview/llwindowlistener.cpp b/indra/newview/llwindowlistener.cpp
index 9e4297baaf..aa8c79b0d2 100644
--- a/indra/newview/llwindowlistener.cpp
+++ b/indra/newview/llwindowlistener.cpp
@@ -37,7 +37,7 @@
#include "llview.h"
#include "llviewinject.h"
#include "llviewerwindow.h"
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
#include "llrootview.h"
#include "llsdutil.h"
#include "stringize.h"
@@ -279,7 +279,7 @@ void LLWindowListener::keyDown(LLSD const & evt)
response.setResponse(target_view->getInfo());
gFocusMgr.setKeyboardFocus(target_view);
- gViewerKeyboard.handleKey(key, mask, false);
+ gViewerInput.handleKey(key, mask, false);
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
else
@@ -291,7 +291,7 @@ void LLWindowListener::keyDown(LLSD const & evt)
}
else
{
- gViewerKeyboard.handleKey(key, mask, false);
+ gViewerInput.handleKey(key, mask, false);
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
}
diff --git a/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp
deleted file mode 100644
index c8879e73eb..0000000000
--- a/indra/newview/llwlanimator.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * @file llwlanimator.cpp
- * @brief Implementation for the LLWLAnimator class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llwlanimator.h"
-#include "llsky.h"
-#include "pipeline.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
-
-extern LLControlGroup gSavedSettings;
-
-F64 LLWLAnimator::INTERP_TOTAL_SECONDS = 3.f;
-
-LLWLAnimator::LLWLAnimator() : mStartTime(0.f), mDayRate(1.f), mDayTime(0.f),
- mIsRunning(FALSE), mIsInterpolating(FALSE), mTimeType(TIME_LINDEN),
- mInterpStartTime(), mInterpEndTime()
-{
- mInterpBeginWL = new LLWLParamSet();
- mInterpBeginWater = new LLWaterParamSet();
- mInterpEndWater = new LLWaterParamSet();
-}
-
-void LLWLAnimator::update(LLWLParamSet& curParams)
-{
- //llassert(mUseLindenTime != mUseLocalTime);
-
- F64 curTime;
- curTime = getDayTime();
-
- // don't do anything if empty
- if(mTimeTrack.size() == 0)
- {
- return;
- }
-
- // start it off
- mFirstIt = mTimeTrack.begin();
- mSecondIt = mTimeTrack.begin();
- mSecondIt++;
-
- // grab the two tween iterators
- while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first)
- {
- mFirstIt++;
- mSecondIt++;
- }
-
- // scroll it around when you get to the end
- if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime)
- {
- mSecondIt = mTimeTrack.begin();
- mFirstIt = mTimeTrack.end();
- mFirstIt--;
- }
-
- F32 weight = 0;
-
- if(mFirstIt->first < mSecondIt->first)
- {
-
- // get the delta time and the proper weight
- weight = F32 (curTime - mFirstIt->first) /
- (mSecondIt->first - mFirstIt->first);
-
- // handle the ends
- }
- else if(mFirstIt->first > mSecondIt->first)
- {
-
- // right edge of time line
- if(curTime >= mFirstIt->first)
- {
- weight = F32 (curTime - mFirstIt->first) /
- ((1 + mSecondIt->first) - mFirstIt->first);
- // left edge of time line
- }
- else
- {
- weight = F32 ((1 + curTime) - mFirstIt->first) /
- ((1 + mSecondIt->first) - mFirstIt->first);
- }
-
- // handle same as whatever the last one is
- }
- else
- {
- weight = 1;
- }
-
- if(mIsInterpolating)
- {
- // *TODO_JACOB: this is kind of laggy. Not sure why. The part that lags is the curParams.mix call, and none of the other mixes. It works, though.
- clock_t current = clock();
- if(current >= mInterpEndTime)
- {
- mIsInterpolating = false;
- return;
- }
-
- // determine moving target for final interpolation value
- // *TODO: this will not work with lazy loading of sky presets.
- LLWLParamSet buf = LLWLParamSet();
- buf.setAll(LLWLParamManager::getInstance()->mParamList[mFirstIt->second].getAll()); // just give it some values, otherwise it has no params to begin with (see comment in constructor)
- buf.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); // mix to determine moving target for interpolation finish (as below)
-
- // mix from previous value to moving target
- weight = (current - mInterpStartTime) / (INTERP_TOTAL_SECONDS * CLOCKS_PER_SEC);
- curParams.mix(*mInterpBeginWL, buf, weight);
-
- // mix water
- LLWaterParamManager::getInstance()->mCurParams.mix(*mInterpBeginWater, *mInterpEndWater, weight);
- }
- else
- {
- // do the interpolation and set the parameters
- // *TODO: this will not work with lazy loading of sky presets.
- curParams.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight);
- }
-}
-
-F64 LLWLAnimator::getDayTime()
-{
- if(!mIsRunning)
- {
- return mDayTime;
- }
- else if(mTimeType == TIME_LINDEN)
- {
- F32 phase = gSky.getSunPhase() / F_PI;
-
- // we're not solving the non-linear equation that determines sun phase
- // we're just linearly interpolating between the major points
-
- if (phase <= 5.0 / 4.0)
- {
- // mDayTime from 0.33 to 0.75 (6:00 to 21:00)
- mDayTime = (1.0 / 3.0) * phase + (1.0 / 3.0);
- }
- else if (phase > 7.0 / 4.0)
- {
- // maximum value for phase is 2
- // mDayTime from 0.25 to 0.33 (3:00 to 6:00)
- mDayTime = (1.0 / 3.0) - (1.0 / 3.0) * (2 - phase);
- }
- else
- {
- // phase == 3/2 is where day restarts (24:00)
- // mDayTime from 0.75 to 0.999 and 0 to 0.25 (21:00 to 03:00)
- mDayTime = phase - (1.0 / 2.0);
-
- if(mDayTime > 1)
- {
- mDayTime--;
- }
- }
-
- return mDayTime;
- }
- else if(mTimeType == TIME_LOCAL)
- {
- return getLocalTime();
- }
-
- // get the time;
- mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate;
-
- // clamp it
- if(mDayTime < 0)
- {
- mDayTime = 0;
- }
- while(mDayTime > 1)
- {
- mDayTime--;
- }
-
- return (F32)mDayTime;
-}
-
-void LLWLAnimator::setDayTime(F64 dayTime)
-{
- //retroactively set start time;
- mStartTime = LLTimer::getElapsedSeconds() - dayTime * mDayRate;
- mDayTime = dayTime;
-
- // clamp it
- if(mDayTime < 0)
- {
- mDayTime = 0;
- }
- else if(mDayTime > 1)
- {
- mDayTime = 1;
- }
-}
-
-
-void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& curTrack,
- F32 dayRate, F64 dayTime, bool run)
-{
- mTimeTrack = curTrack;
- mDayRate = dayRate;
- setDayTime(dayTime);
-
- mIsRunning = run;
-}
-
-void LLWLAnimator::startInterpolation(const LLSD& targetWater)
-{
- mInterpBeginWL->setAll(LLWLParamManager::getInstance()->mCurParams.getAll());
- mInterpBeginWater->setAll(LLWaterParamManager::getInstance()->mCurParams.getAll());
-
- mInterpStartTime = clock();
- mInterpEndTime = mInterpStartTime + clock_t(INTERP_TOTAL_SECONDS) * CLOCKS_PER_SEC;
-
- // Don't set any ending WL -- this is continuously calculated as the animator updates since it's a moving target
- mInterpEndWater->setAll(targetWater);
-
- mIsInterpolating = true;
-}
-
-std::string LLWLAnimator::timeToString(F32 curTime)
-{
- S32 hours;
- S32 min;
- bool isPM = false;
-
- // get hours and minutes
- hours = (S32) (24.0 * curTime);
- curTime -= ((F32) hours / 24.0f);
- min = ll_round(24.0f * 60.0f * curTime);
-
- // handle case where it's 60
- if(min == 60)
- {
- hours++;
- min = 0;
- }
-
- // set for PM
- if(hours >= 12 && hours < 24)
- {
- isPM = true;
- }
-
- // convert to non-military notation
- if(hours >= 24)
- {
- hours = 12;
- }
- else if(hours > 12)
- {
- hours -= 12;
- }
- else if(hours == 0)
- {
- hours = 12;
- }
-
- // make the string
- std::stringstream newTime;
- newTime << hours << ":";
-
- // double 0
- if(min < 10)
- {
- newTime << 0;
- }
-
- // finish it
- newTime << min << " ";
- if(isPM)
- {
- newTime << "PM";
- }
- else
- {
- newTime << "AM";
- }
-
- return newTime.str();
-}
-
-F64 LLWLAnimator::getLocalTime()
-{
- char buffer[9];
- time_t rawtime;
- struct tm* timeinfo;
-
- time(&rawtime);
- timeinfo = localtime(&rawtime);
- strftime(buffer, 9, "%H:%M:%S", timeinfo);
- std::string timeStr(buffer);
-
- F64 tod = ((F64)atoi(timeStr.substr(0,2).c_str())) / 24.f +
- ((F64)atoi(timeStr.substr(3,2).c_str())) / 1440.f +
- ((F64)atoi(timeStr.substr(6,2).c_str())) / 86400.f;
- return tod;
-}
diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h
deleted file mode 100644
index e2e49c7305..0000000000
--- a/indra/newview/llwlanimator.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * @file llwlanimator.h
- * @brief Interface for the LLWLAnimator class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_WL_ANIMATOR_H
-#define LL_WL_ANIMATOR_H
-
-#include "llwlparamset.h"
-#include "llenvmanager.h"
-#include "llwaterparamset.h"
-#include <string>
-#include <map>
-
-class LLWLAnimator {
-public:
- typedef enum e_time
- {
- TIME_LINDEN,
- TIME_LOCAL,
- TIME_CUSTOM
- } ETime;
-
- F64 mStartTime;
- F32 mDayRate;
- F64 mDayTime;
-
- // track to play
- std::map<F32, LLWLParamKey> mTimeTrack;
- std::map<F32, LLWLParamKey>::iterator mFirstIt, mSecondIt;
-
- // simple constructor
- LLWLAnimator();
-
- ~LLWLAnimator()
- {
- delete mInterpBeginWL;
- delete mInterpBeginWater;
- delete mInterpEndWater;
- }
-
- // update the parameters
- void update(LLWLParamSet& curParams);
-
- // get time in seconds
- //F64 getTime(void);
-
- // returns a float 0 - 1 saying what time of day is it?
- F64 getDayTime(void);
-
- // sets a float 0 - 1 saying what time of day it is
- void setDayTime(F64 dayTime);
-
- // set an animation track
- void setTrack(std::map<F32, LLWLParamKey>& track,
- F32 dayRate, F64 dayTime = 0, bool run = true);
-
- void deactivate()
- {
- mIsRunning = false;
- }
-
- void activate(ETime time)
- {
- mIsRunning = true;
- mTimeType = time;
- }
-
- void startInterpolation(const LLSD& targetWater);
-
- bool getIsRunning()
- {
- return mIsRunning;
- }
-
- bool getUseCustomTime()
- {
- return mTimeType == TIME_CUSTOM;
- }
-
- bool getUseLocalTime()
- {
- return mTimeType == TIME_LOCAL;
- }
-
- bool getUseLindenTime()
- {
- return mTimeType == TIME_LINDEN;
- }
-
- void setTimeType(ETime time)
- {
- mTimeType = time;
- }
-
- ETime getTimeType()
- {
- return mTimeType;
- }
-
- /// convert the present time to a digital clock time
- static std::string timeToString(F32 curTime);
-
- /// get local time between 0 and 1
- static F64 getLocalTime();
-
-private:
- ETime mTimeType;
- bool mIsRunning, mIsInterpolating;
- LLWLParamSet *mInterpBeginWL;
- LLWaterParamSet *mInterpBeginWater, *mInterpEndWater;
- clock_t mInterpStartTime, mInterpEndTime;
-
- static F64 INTERP_TOTAL_SECONDS;
-};
-
-#endif // LL_WL_ANIMATOR_H
-
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 106f17f61b..0a331d1823 100644
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
@@ -46,6 +46,7 @@ LLWLDayCycle::~LLWLDayCycle()
void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope)
{
+#if 0
LL_DEBUGS() << "Loading day cycle (day_data.size() = " << day_data.size() << ", scope = " << scope << ")" << LL_ENDL;
mTimeMap.clear();
@@ -88,6 +89,7 @@ void LLWLDayCycle::loadDayCycle(const LLSD& day_data, LLWLParamKey::EScope scope
// then add the keyframe
addKeyframe((F32)day_data[i][0].asReal(), frame);
}
+#endif
}
void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName)
@@ -158,35 +160,35 @@ LLSD LLWLDayCycle::asLLSD()
return day_data;
}
-bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const
-{
- bool result = true;
- LLWLParamManager& wl_mgr = LLWLParamManager::instance();
-
- refs.clear();
- for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter)
- {
- const LLWLParamKey& key = iter->second;
- if (!wl_mgr.getParamSet(key, refs[key]))
- {
- LL_WARNS() << "Cannot find sky [" << key.name << "] referenced by a day cycle" << LL_ENDL;
- result = false;
- }
- }
-
- return result;
-}
+// bool LLWLDayCycle::getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const
+// {
+// bool result = true;
+// LLWLParamManager& wl_mgr = LLWLParamManager::instance();
+//
+// refs.clear();
+// for (std::map<F32, LLWLParamKey>::const_iterator iter = mTimeMap.begin(); iter != mTimeMap.end(); ++iter)
+// {
+// const LLWLParamKey& key = iter->second;
+// if (!wl_mgr.getParamSet(key, refs[key]))
+// {
+// LL_WARNS() << "Cannot find sky [" << key.name << "] referenced by a day cycle" << LL_ENDL;
+// result = false;
+// }
+// }
+//
+// return result;
+// }
bool LLWLDayCycle::getSkyMap(LLSD& sky_map) const
{
- std::map<LLWLParamKey, LLWLParamSet> refs;
-
- if (!getSkyRefs(refs))
- {
- return false;
- }
-
- sky_map = LLWLParamManager::createSkyMap(refs);
+// std::map<LLWLParamKey, LLWLParamSet> refs;
+//
+// if (!getSkyRefs(refs))
+// {
+// return false;
+// }
+//
+// sky_map = LLWLParamManager::createSkyMap(refs);
return true;
}
@@ -235,23 +237,23 @@ bool LLWLDayCycle::changeKeyframeTime(F32 oldTime, F32 newTime)
return addKeyframe(newTime, frame);
}
-bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key)
-{
- LL_DEBUGS() << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL;
-
- // just remove and add back
- // make sure param exists
- LLWLParamSet tmp;
- bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp);
- if(stat == false)
- {
- LL_DEBUGS() << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL;
- return stat;
- }
-
- mTimeMap[time] = key;
- return true;
-}
+// bool LLWLDayCycle::changeKeyframeParam(F32 time, LLWLParamKey key)
+// {
+// LL_DEBUGS() << "Changing key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL;
+//
+// // just remove and add back
+// // make sure param exists
+// LLWLParamSet tmp;
+// bool stat = LLWLParamManager::getInstance()->getParamSet(key, tmp);
+// if(stat == false)
+// {
+// LL_DEBUGS() << "Failed to change key frame param (" << time << ", " << key.toLLSD() << ")" << LL_ENDL;
+// return stat;
+// }
+//
+// mTimeMap[time] = key;
+// return true;
+// }
bool LLWLDayCycle::removeKeyframe(F32 time)
@@ -285,19 +287,19 @@ bool LLWLDayCycle::getKeytime(LLWLParamKey frame, F32& key_time) const
return false;
}
-bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param)
-{
- // just scroll on through till you find it
- std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
- if(mIt != mTimeMap.end())
- {
- return LLWLParamManager::getInstance()->getParamSet(mIt->second, param);
- }
-
- // return error if not found
- LL_DEBUGS() << "Key " << time << " not found" << LL_ENDL;
- return false;
-}
+// bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param)
+// {
+// // just scroll on through till you find it
+// std::map<F32, LLWLParamKey>::iterator mIt = mTimeMap.find(time);
+// if(mIt != mTimeMap.end())
+// {
+// return LLWLParamManager::getInstance()->getParamSet(mIt->second, param);
+// }
+//
+// // return error if not found
+// LL_DEBUGS() << "Key " << time << " not found" << LL_ENDL;
+// return false;
+// }
bool LLWLDayCycle::getKeyedParamName(F32 time, std::string & name)
{
diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h
index c8585564ed..2f9a2e5c4a 100644
--- a/indra/newview/llwldaycycle.h
+++ b/indra/newview/llwldaycycle.h
@@ -32,10 +32,8 @@ class LLWLDayCycle;
#include <vector>
#include <map>
#include <string>
-#include "llwlparamset.h"
-#include "llwlanimator.h"
+#include "llenvmanager.h"
struct LLWLParamKey;
-#include "llenvmanager.h" // for LLEnvKey::EScope
class LLWLDayCycle
{
@@ -78,7 +76,7 @@ public:
LLSD asLLSD();
// get skies referenced by this day cycle
- bool getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const;
+// bool getSkyRefs(std::map<LLWLParamKey, LLWLParamSet>& refs) const;
// get referenced skies as LLSD
bool getSkyMap(LLSD& sky_map) const;
@@ -110,7 +108,7 @@ public:
/// get the param set at a given time
/// returns true if found one
- bool getKeyedParam(F32 time, LLWLParamSet& param);
+// bool getKeyedParam(F32 time, LLWLParamSet& param);
/// get the name
/// returns true if it found one
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index ea65a0c6d9..730aa3774f 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -30,15 +30,15 @@
#include "llagent.h"
#include "llviewerregion.h"
-#include "llenvmanager.h"
#include "llnotificationsutil.h"
#include "llcorehttputil.h"
+#include "llparcel.h"
/****
* LLEnvironmentRequest
****/
// static
-bool LLEnvironmentRequest::initiate()
+bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
{
LLViewerRegion* cur_region = gAgent.getRegion();
@@ -51,15 +51,15 @@ bool LLEnvironmentRequest::initiate()
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
- cur_region->setCapabilitiesReceivedCallback(boost::bind(&LLEnvironmentRequest::onRegionCapsReceived, _1));
+ cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
return false;
}
- return doRequest();
+ return doRequest(cb);
}
// static
-void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id)
+void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id, LLEnvironment::environment_apply_fn cb)
{
if (region_id != gAgent.getRegion()->getRegionID())
{
@@ -68,23 +68,26 @@ void LLEnvironmentRequest::onRegionCapsReceived(const LLUUID& region_id)
}
LL_DEBUGS("WindlightCaps") << "Received region capabilities" << LL_ENDL;
- doRequest();
+ doRequest(cb);
}
// static
-bool LLEnvironmentRequest::doRequest()
+bool LLEnvironmentRequest::doRequest(LLEnvironment::environment_apply_fn cb)
{
std::string url = gAgent.getRegionCapability("EnvironmentSettings");
if (url.empty())
{
LL_INFOS("WindlightCaps") << "Skipping windlight setting request - we don't have this capability" << LL_ENDL;
// region is apparently not capable of this; don't respond at all
+ // (there shouldn't be any regions where this is the case... but
+ LL_INFOS("ENVIRONMENT") << "No legacy windlight caps... just set the region to be the default day." << LL_ENDL;
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_REGION, LLSettingsDay::GetDefaultAssetId());
return false;
}
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
- boost::bind(&LLEnvironmentRequest::environmentRequestCoro, url));
+ [url, cb]() { LLEnvironmentRequest::environmentRequestCoro(url, cb); });
LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
return true;
@@ -93,7 +96,7 @@ bool LLEnvironmentRequest::doRequest()
S32 LLEnvironmentRequest::sLastRequest = 0;
//static
-void LLEnvironmentRequest::environmentRequestCoro(std::string url)
+void LLEnvironmentRequest::environmentRequestCoro(std::string url, LLEnvironment::environment_apply_fn cb)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
S32 requestId = ++LLEnvironmentRequest::sLastRequest;
@@ -103,6 +106,8 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url)
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+ LL_WARNS("WindlightCaps") << "Using legacy Windlight caps." << LL_ENDL;
+
if (requestId != LLEnvironmentRequest::sLastRequest)
{
LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
@@ -114,11 +119,12 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url)
if (!status)
{
LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... " << LL_ENDL;
- LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_REGION, LLSettingsDay::GetDefaultAssetId());
+
return;
}
result = result["content"];
- LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
+ LL_INFOS("WindlightCaps") << "Received region legacy windlight settings" << LL_ENDL;
LLUUID regionId;
if (gAgent.getRegion())
@@ -134,7 +140,12 @@ void LLEnvironmentRequest::environmentRequestCoro(std::string url)
return;
}
- LLEnvManagerNew::getInstance()->onRegionSettingsResponse(result);
+ if (cb)
+ {
+ LLEnvironment::EnvironmentInfo::ptr_t pinfo = LLEnvironment::EnvironmentInfo::extractLegacy(result);
+
+ cb(INVALID_PARCEL_ID, pinfo);
+ }
}
@@ -146,7 +157,7 @@ clock_t LLEnvironmentApply::UPDATE_WAIT_SECONDS = clock_t(3.f);
clock_t LLEnvironmentApply::sLastUpdate = clock_t(0.f);
// static
-bool LLEnvironmentApply::initiateRequest(const LLSD& content)
+bool LLEnvironmentApply::initiateRequest(const LLSD& content, LLEnvironment::environment_apply_fn cb)
{
clock_t current = clock();
@@ -162,7 +173,7 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
sLastUpdate = current;
// Send update request.
- std::string url = gAgent.getRegionCapability("EnvironmentSettings");
+ std::string url = gAgent.getRegionCapability("ExtEnvironment");
if (url.empty())
{
LL_WARNS("WindlightCaps") << "Applying windlight settings not supported" << LL_ENDL;
@@ -174,11 +185,11 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
std::string coroname =
LLCoros::instance().launch("LLEnvironmentApply::environmentApplyCoro",
- boost::bind(&LLEnvironmentApply::environmentApplyCoro, url, content));
+ [url, content, cb]() { LLEnvironmentApply::environmentApplyCoro(url, content, cb); });
return true;
}
-void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content)
+void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content, LLEnvironment::environment_apply_fn cb)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -242,13 +253,11 @@ void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content)
}
LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << result["regionID"].asUUID() << LL_ENDL;
- LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
} while (false);
if (!notify.isUndefined())
{
LLNotificationsUtil::add("WLRegionApplyFail", notify);
- LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
}
}
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index eb2bbf9553..b09d2df60f 100644
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -29,19 +29,20 @@
#include "llviewerprecompiledheaders.h"
#include "llcoros.h"
+#include "llenvironment.h"
class LLEnvironmentRequest
{
LOG_CLASS(LLEnvironmentRequest);
public:
/// @return true if request was successfully sent
- static bool initiate();
+ static bool initiate(LLEnvironment::environment_apply_fn cb);
private:
- static void onRegionCapsReceived(const LLUUID& region_id);
- static bool doRequest();
+ static void onRegionCapsReceived(const LLUUID& region_id, LLEnvironment::environment_apply_fn cb);
+ static bool doRequest(LLEnvironment::environment_apply_fn cb);
- static void environmentRequestCoro(std::string url);
+ static void environmentRequestCoro(std::string url, LLEnvironment::environment_apply_fn cb);
static S32 sLastRequest;
};
@@ -51,13 +52,15 @@ class LLEnvironmentApply
LOG_CLASS(LLEnvironmentApply);
public:
/// @return true if request was successfully sent
- static bool initiateRequest(const LLSD& content);
+ static bool initiateRequest(const LLSD& content, LLEnvironment::environment_apply_fn cb);
private:
static clock_t sLastUpdate;
static clock_t UPDATE_WAIT_SECONDS;
- static void environmentApplyCoro(std::string url, LLSD content);
+ static void environmentApplyCoro(std::string url, LLSD content, LLEnvironment::environment_apply_fn cb);
};
+
+
#endif // LL_LLWLHANDLERS_H
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
deleted file mode 100644
index 4b4393b07b..0000000000
--- a/indra/newview/llwlparammanager.cpp
+++ /dev/null
@@ -1,710 +0,0 @@
-/**
- * @file llwlparammanager.cpp
- * @brief Implementation for the LLWLParamManager class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llwlparammanager.h"
-
-#include "pipeline.h"
-#include "llsky.h"
-
-#include "lldiriterator.h"
-#include "llfloaterreg.h"
-#include "llsliderctrl.h"
-#include "llspinctrl.h"
-#include "llcheckboxctrl.h"
-#include "lluictrlfactory.h"
-#include "llviewercamera.h"
-#include "llcombobox.h"
-#include "lllineeditor.h"
-#include "llsdserialize.h"
-
-#include "v4math.h"
-#include "llviewerdisplay.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-#include "lldrawpoolwater.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-
-#include "llwlparamset.h"
-#include "llpostprocess.h"
-
-#include "llviewershadermgr.h"
-#include "llglslshader.h"
-
-#include "curl/curl.h"
-#include "llstreamtools.h"
-
-LLWLParamManager::LLWLParamManager() :
-
- //set the defaults for the controls
-
- /// Sun Delta Terrain tweak variables.
- mSunDeltaYaw(180.0f),
- mSceneLightStrength(2.0f),
- mWLGamma(1.0f, "gamma"),
-
- mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"),
- mHazeDensity(1.0f, "haze_density"),
- mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"),
- mDensityMult(1.0f, "density_multiplier", 1000),
- mHazeHorizon(1.0f, "haze_horizon"),
- mMaxAlt(4000.0f, "max_y"),
-
- // Lighting
- mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"),
- mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"),
- mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"),
- mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"),
-
- // Clouds
- mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"),
- mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"),
- mCloudCoverage(0.0f, "cloud_shadow"),
- mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"),
- mDistanceMult(1.0f, "distance_multiplier"),
- mCloudScale(0.42f, "cloud_scale"),
-
- // sky dome
- mDomeOffset(0.96f),
- mDomeRadius(15000.f)
-{
-}
-
-LLWLParamManager::~LLWLParamManager()
-{
-}
-
-void LLWLParamManager::clearParamSetsOfScope(LLWLParamKey::EScope scope)
-{
- if (LLWLParamKey::SCOPE_LOCAL == scope)
- {
- LL_WARNS("Windlight") << "Tried to clear windlight sky presets from local system! This shouldn't be called..." << LL_ENDL;
- return;
- }
-
- std::set<LLWLParamKey> to_remove;
- for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = mParamList.begin(); iter != mParamList.end(); ++iter)
- {
- if(iter->first.scope == scope)
- {
- to_remove.insert(iter->first);
- }
- }
-
- for(std::set<LLWLParamKey>::iterator iter = to_remove.begin(); iter != to_remove.end(); ++iter)
- {
- mParamList.erase(*iter);
- }
-}
-
-// returns all skies referenced by the day cycle, with their final names
-// side effect: applies changes to all internal structures!
-std::map<LLWLParamKey, LLWLParamSet> LLWLParamManager::finalizeFromDayCycle(LLWLParamKey::EScope scope)
-{
- LL_DEBUGS() << "mDay before finalizing:" << LL_ENDL;
- {
- for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter)
- {
- LLWLParamKey& key = iter->second;
- LL_DEBUGS() << iter->first << "->" << key.name << LL_ENDL;
- }
- }
-
- std::map<LLWLParamKey, LLWLParamSet> final_references;
-
- // Move all referenced to desired scope, renaming if necessary
- // First, save skies referenced
- std::map<LLWLParamKey, LLWLParamSet> current_references; // all skies referenced by the day cycle, with their current names
- // guard against skies with same name and different scopes
- std::set<std::string> inserted_names;
- std::map<std::string, unsigned int> conflicted_names; // integer later used as a count, for uniquely renaming conflicts
-
- LLWLDayCycle& cycle = mDay;
- for(std::map<F32, LLWLParamKey>::iterator iter = cycle.mTimeMap.begin();
- iter != cycle.mTimeMap.end();
- ++iter)
- {
- LLWLParamKey& key = iter->second;
- std::string desired_name = key.name;
- replace_newlines_with_whitespace(desired_name); // already shouldn't have newlines, but just in case
- if(inserted_names.find(desired_name) == inserted_names.end())
- {
- inserted_names.insert(desired_name);
- }
- else
- {
- // make exist in map
- conflicted_names[desired_name] = 0;
- }
- current_references[key] = mParamList[key];
- }
-
- // forget all old skies in target scope, and rebuild, renaming as needed
- clearParamSetsOfScope(scope);
- for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = current_references.begin(); iter != current_references.end(); ++iter)
- {
- const LLWLParamKey& old_key = iter->first;
-
- std::string desired_name(old_key.name);
- replace_newlines_with_whitespace(desired_name);
-
- LLWLParamKey new_key(desired_name, scope); // name will be replaced later if necessary
-
- // if this sky is one with a non-unique name, rename via appending a number
- // an existing preset of the target scope gets to keep its name
- if (scope != old_key.scope && conflicted_names.find(desired_name) != conflicted_names.end())
- {
- std::string& new_name = new_key.name;
-
- do
- {
- // if this executes more than once, this is an absurdly pathological case
- // (e.g. "x" repeated twice, but "x 1" already exists, so need to use "x 2")
- std::stringstream temp;
- temp << desired_name << " " << (++conflicted_names[desired_name]);
- new_name = temp.str();
- } while (inserted_names.find(new_name) != inserted_names.end());
-
- // yay, found one that works
- inserted_names.insert(new_name); // track names we consume here; shouldn't be necessary due to ++int? but just in case
-
- // *TODO factor out below into a rename()?
-
- LL_INFOS("Windlight") << "Renamed " << old_key.name << " (scope" << old_key.scope << ") to "
- << new_key.name << " (scope " << new_key.scope << ")" << LL_ENDL;
-
- // update name in sky
- iter->second.mName = new_name;
-
- // update keys in day cycle
- for(std::map<F32, LLWLParamKey>::iterator frame = cycle.mTimeMap.begin(); frame != cycle.mTimeMap.end(); ++frame)
- {
- if (frame->second == old_key)
- {
- frame->second = new_key;
- }
- }
-
- // add to master sky map
- mParamList[new_key] = iter->second;
- }
-
- final_references[new_key] = iter->second;
- }
-
- LL_DEBUGS() << "mDay after finalizing:" << LL_ENDL;
- {
- for (std::map<F32, LLWLParamKey>::iterator iter = mDay.mTimeMap.begin(); iter != mDay.mTimeMap.end(); ++iter)
- {
- LLWLParamKey& key = iter->second;
- LL_DEBUGS() << iter->first << "->" << key.name << LL_ENDL;
- }
- }
-
- return final_references;
-}
-
-// static
-LLSD LLWLParamManager::createSkyMap(std::map<LLWLParamKey, LLWLParamSet> refs)
-{
- LLSD skies = LLSD::emptyMap();
- for(std::map<LLWLParamKey, LLWLParamSet>::iterator iter = refs.begin(); iter != refs.end(); ++iter)
- {
- skies.insert(iter->first.name, iter->second.getAll());
- }
- return skies;
-}
-
-void LLWLParamManager::addAllSkies(const LLWLParamKey::EScope scope, const LLSD& sky_presets)
-{
- for(LLSD::map_const_iterator iter = sky_presets.beginMap(); iter != sky_presets.endMap(); ++iter)
- {
- LLWLParamSet set;
- set.setAll(iter->second);
- mParamList[LLWLParamKey(iter->first, scope)] = set;
- }
-}
-
-void LLWLParamManager::refreshRegionPresets(const LLSD& region_sky_presets)
-{
- // Remove all region sky presets because they may belong to a previously visited region.
- clearParamSetsOfScope(LLEnvKey::SCOPE_REGION);
-
- // Add all sky presets belonging to the current region.
- addAllSkies(LLEnvKey::SCOPE_REGION, region_sky_presets);
-}
-
-void LLWLParamManager::loadAllPresets()
-{
- // First, load system (coming out of the box) sky presets.
- loadPresetsFromDir(getSysDir());
-
- // Then load user presets. Note that user day presets will modify any system ones already loaded.
- loadPresetsFromDir(getUserDir());
-}
-
-void LLWLParamManager::loadPresetsFromDir(const std::string& dir)
-{
- LL_INFOS("AppInit", "Shaders") << "Loading sky presets from " << dir << LL_ENDL;
-
- LLDirIterator dir_iter(dir, "*.xml");
- while (1)
- {
- std::string file;
- if (!dir_iter.next(file))
- {
- break; // no more files
- }
-
- std::string path = gDirUtilp->add(dir, file);
- if (!loadPreset(path))
- {
- LL_WARNS() << "Error loading sky preset from " << path << LL_ENDL;
- }
- }
-}
-
-bool LLWLParamManager::loadPreset(const std::string& path)
-{
- llifstream xml_file;
- std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
-
- xml_file.open(path.c_str());
- if (!xml_file)
- {
- return false;
- }
-
- LL_DEBUGS("AppInit", "Shaders") << "Loading sky " << name << LL_ENDL;
-
- LLSD params_data;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- parser->parse(xml_file, params_data, LLSDSerialize::SIZE_UNLIMITED);
- xml_file.close();
-
- LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL);
- if (hasParamSet(key))
- {
- setParamSet(key, params_data);
- }
- else
- {
- addParamSet(key, params_data);
- }
-
- return true;
-}
-
-void LLWLParamManager::savePreset(LLWLParamKey key)
-{
- llassert(key.scope == LLEnvKey::SCOPE_LOCAL && !key.name.empty());
-
- // make an empty llsd
- LLSD paramsData(LLSD::emptyMap());
- std::string pathName(getUserDir() + escapeString(key.name) + ".xml");
-
- // fill it with LLSD windlight params
- paramsData = mParamList[key].getAll();
-
- // write to file
- llofstream presetsXML(pathName.c_str());
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
- presetsXML.close();
-
- propagateParameters();
-}
-
-void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
-{
- if (gPipeline.canUseWindLightShaders())
- {
- mCurParams.update(shader);
- }
-
- if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
- {
- shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- }
-
- else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
- {
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
- }
-
- shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
-
-}
-
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_WLPARAM("Update Windlight Params");
-
-void LLWLParamManager::propagateParameters(void)
-{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_WLPARAM);
-
- LLVector4 sunDir;
- LLVector4 moonDir;
-
- // set the sun direction from SunAngle and EastAngle
- F32 sinTheta = sin(mCurParams.getEastAngle());
- F32 cosTheta = cos(mCurParams.getEastAngle());
-
- F32 sinPhi = sin(mCurParams.getSunAngle());
- F32 cosPhi = cos(mCurParams.getSunAngle());
-
- sunDir.mV[0] = -sinTheta * cosPhi;
- sunDir.mV[1] = sinPhi;
- sunDir.mV[2] = cosTheta * cosPhi;
- sunDir.mV[3] = 0;
-
- moonDir = -sunDir;
-
- // is the normal from the sun or the moon
- if(sunDir.mV[1] >= 0)
- {
- mLightDir = sunDir;
- }
- else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS)
- {
- // clamp v1 to 0 so sun never points up and causes weirdness on some machines
- LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);
- vec.mV[1] = 0;
- vec.normVec();
- mLightDir = LLVector4(vec, 0.f);
- }
- else
- {
- mLightDir = moonDir;
- }
-
- // calculate the clamp lightnorm for sky (to prevent ugly banding in sky
- // when haze goes below the horizon
- mClampedLightDir = sunDir;
-
- if (mClampedLightDir.mV[1] < -0.1f)
- {
- mClampedLightDir.mV[1] = -0.1f;
- }
-
- mCurParams.set("lightnorm", mLightDir);
-
- // bind the variables for all shaders only if we're using WindLight
- LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
- end_shaders = LLViewerShaderMgr::instance()->endShaders();
- for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
- {
- if (shaders_iter->mProgramObject != 0
- && (gPipeline.canUseWindLightShaders()
- || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
- {
- shaders_iter->mUniformsDirty = TRUE;
- }
- }
-
- // get the cfr version of the sun's direction
- LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]);
-
- // set direction and don't allow overriding
- gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0));
- gSky.setOverrideSun(TRUE);
-}
-
-void LLWLParamManager::update(LLViewerCamera * cam)
-{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_WLPARAM);
-
- // update clouds, sun, and general
- mCurParams.updateCloudScrolling();
-
- // update only if running
- if(mAnimator.getIsRunning())
- {
- mAnimator.update(mCurParams);
- }
-
- // update the shaders and the menu
- propagateParameters();
-
- F32 camYaw = cam->getYaw();
-
- stop_glerror();
-
- // *TODO: potential optimization - this block may only need to be
- // executed some of the time. For example for water shaders only.
- {
- F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD;
-
- LLVector3 lightNorm3(mLightDir);
- lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f));
- mRotatedLightDir = LLVector4(lightNorm3, 0.f);
-
- LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
- end_shaders = LLViewerShaderMgr::instance()->endShaders();
- for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
- {
- if (shaders_iter->mProgramObject != 0
- && (gPipeline.canUseWindLightShaders()
- || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
- {
- shaders_iter->mUniformsDirty = TRUE;
- }
- }
- }
-}
-
-bool LLWLParamManager::applyDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time)
-{
- mDay.loadDayCycle(params, scope);
- resetAnimator(time, true); // set to specified time and start animator
- return true;
-}
-
-void LLWLParamManager::setDefaultDay()
-{
- mDay.loadDayCycleFromFile("Default.xml");
-}
-
-bool LLWLParamManager::applySkyParams(const LLSD& params)
-{
- mAnimator.deactivate();
- mCurParams.setAll(params);
- return true;
-}
-
-void LLWLParamManager::setDefaultSky()
-{
- getParamSet(LLWLParamKey("Default", LLWLParamKey::SCOPE_LOCAL), mCurParams);
-}
-
-
-void LLWLParamManager::resetAnimator(F32 curTime, bool run)
-{
- mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate,
- curTime, run);
-
- return;
-}
-
-bool LLWLParamManager::addParamSet(const LLWLParamKey& key, LLWLParamSet& param)
-{
- // add a new one if not one there already
- std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key);
- if(mIt == mParamList.end())
- {
- llassert(!key.name.empty());
- // *TODO: validate params
- mParamList[key] = param;
- mPresetListChangeSignal();
- return true;
- }
-
- return false;
-}
-
-BOOL LLWLParamManager::addParamSet(const LLWLParamKey& key, LLSD const & param)
-{
- LLWLParamSet param_set;
- param_set.setAll(param);
- return addParamSet(key, param_set);
-}
-
-bool LLWLParamManager::getParamSet(const LLWLParamKey& key, LLWLParamSet& param)
-{
- // find it and set it
- std::map<LLWLParamKey, LLWLParamSet>::iterator mIt = mParamList.find(key);
- if(mIt != mParamList.end())
- {
- param = mParamList[key];
- param.mName = key.name;
- return true;
- }
-
- return false;
-}
-
-bool LLWLParamManager::hasParamSet(const LLWLParamKey& key)
-{
- LLWLParamSet dummy;
- return getParamSet(key, dummy);
-}
-
-bool LLWLParamManager::setParamSet(const LLWLParamKey& key, LLWLParamSet& param)
-{
- llassert(!key.name.empty());
- // *TODO: validate params
- mParamList[key] = param;
-
- return true;
-}
-
-bool LLWLParamManager::setParamSet(const LLWLParamKey& key, const LLSD & param)
-{
- llassert(!key.name.empty());
- // *TODO: validate params
-
- // quick, non robust (we won't be working with files, but assets) check
- // this might not actually be true anymore....
- if(!param.isMap())
- {
- return false;
- }
-
- LLWLParamSet param_set;
- param_set.setAll(param);
- return setParamSet(key, param_set);
-}
-
-void LLWLParamManager::removeParamSet(const LLWLParamKey& key, bool delete_from_disk)
-{
- // *NOTE: Removing a sky preset invalidates day cycles that refer to it.
-
- if (key.scope == LLEnvKey::SCOPE_REGION)
- {
- LL_WARNS() << "Removing region skies not supported" << LL_ENDL;
- llassert(key.scope == LLEnvKey::SCOPE_LOCAL);
- return;
- }
-
- // remove from param list
- std::map<LLWLParamKey, LLWLParamSet>::iterator it = mParamList.find(key);
- if (it == mParamList.end())
- {
- LL_WARNS("WindLight") << "No sky preset named " << key.name << LL_ENDL;
- return;
- }
-
- mParamList.erase(it);
- mDay.removeReferencesTo(key);
-
- // remove from file system if requested
- if (delete_from_disk)
- {
- std::string path_name(getUserDir());
- std::string escaped_name = escapeString(key.name);
-
- if(gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml") < 1)
- {
- LL_WARNS("WindLight") << "Error removing sky preset " << key.name << " from disk" << LL_ENDL;
- }
- }
-
- // signal interested parties
- mPresetListChangeSignal();
-}
-
-bool LLWLParamManager::isSystemPreset(const std::string& preset_name) const
-{
- // *TODO: file system access is excessive here.
- return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml");
-}
-
-void LLWLParamManager::getPresetNames(preset_name_list_t& region, preset_name_list_t& user, preset_name_list_t& sys) const
-{
- region.clear();
- user.clear();
- sys.clear();
-
- for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++)
- {
- const LLWLParamKey& key = it->first;
- const std::string& name = key.name;
-
- if (key.scope == LLEnvKey::SCOPE_REGION)
- {
- region.push_back(name);
- }
- else
- {
- if (isSystemPreset(name))
- {
- sys.push_back(name);
- }
- else
- {
- user.push_back(name);
- }
- }
- }
-}
-
-void LLWLParamManager::getUserPresetNames(preset_name_list_t& user) const
-{
- preset_name_list_t region, sys; // unused
- getPresetNames(region, user, sys);
-}
-
-void LLWLParamManager::getPresetKeys(preset_key_list_t& keys) const
-{
- keys.clear();
-
- for (std::map<LLWLParamKey, LLWLParamSet>::const_iterator it = mParamList.begin(); it != mParamList.end(); it++)
- {
- keys.push_back(it->first);
- }
-}
-
-boost::signals2::connection LLWLParamManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
-{
- return mPresetListChangeSignal.connect(cb);
-}
-
-// virtual static
-void LLWLParamManager::initSingleton()
-{
- LL_DEBUGS("Windlight") << "Initializing sky" << LL_ENDL;
-
- loadAllPresets();
-
- // but use linden time sets it to what the estate is
- mAnimator.setTimeType(LLWLAnimator::TIME_LINDEN);
-}
-
-// static
-std::string LLWLParamManager::getSysDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "");
-}
-
-// static
-std::string LLWLParamManager::getUserDir()
-{
- return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/skies", "");
-}
-
-// static
-std::string LLWLParamManager::escapeString(const std::string& str)
-{
- // Don't use LLURI::escape() because it doesn't encode '-' characters
- // which may break handling of some system presets like "A-12AM".
- char* curl_str = curl_escape(str.c_str(), str.size());
- std::string escaped_str(curl_str);
- curl_free(curl_str);
-
- return escaped_str;
-}
diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
deleted file mode 100644
index 61f86b747f..0000000000
--- a/indra/newview/llwlparammanager.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/**
- * @file llwlparammanager.h
- * @brief Implementation for the LLWLParamManager class.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_WLPARAMMANAGER_H
-#define LL_WLPARAMMANAGER_H
-
-#include <list>
-#include <map>
-#include "llwlparamset.h"
-#include "llwlanimator.h"
-#include "llwldaycycle.h"
-#include "llviewercamera.h"
-#include "lltrans.h"
-
-class LLGLSLShader;
-
-// color control
-struct WLColorControl {
-
- F32 r, g, b, i; /// the values
- std::string mName; /// name to use to dereference params
- std::string mSliderName; /// name of the slider in menu
- bool hasSliderName; /// only set slider name for true color types
- bool isSunOrAmbientColor; /// flag for if it's the sun or ambient color controller
- bool isBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller
-
- inline WLColorControl(F32 red, F32 green, F32 blue, F32 intensity,
- const std::string& n, const std::string& sliderName = LLStringUtil::null)
- : r(red), g(green), b(blue), i(intensity), mName(n), mSliderName(sliderName)
- {
- // if there's a slider name, say we have one
- hasSliderName = false;
- if (mSliderName != "") {
- hasSliderName = true;
- }
-
- // if it's the sun controller
- isSunOrAmbientColor = false;
- if (mSliderName == "WLSunlight" || mSliderName == "WLAmbient") {
- isSunOrAmbientColor = true;
- }
-
- isBlueHorizonOrDensity = false;
- if (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity") {
- isBlueHorizonOrDensity = true;
- }
- }
-
- inline WLColorControl & operator = (LLVector4 const & val) {
- r = val.mV[0];
- g = val.mV[1];
- b = val.mV[2];
- i = val.mV[3];
- return *this;
- }
-
- inline operator LLVector4 (void) const {
- return LLVector4(r, g, b, i);
- }
-
- inline operator LLVector3 (void) const {
- return LLVector3(r, g, b);
- }
-
- inline void update(LLWLParamSet & params) const {
- params.set(mName, r, g, b, i);
- }
-};
-
-// float slider control
-struct WLFloatControl {
- F32 x;
- std::string mName;
- F32 mult;
-
- inline WLFloatControl(F32 val, const std::string& n, F32 m=1.0f)
- : x(val), mName(n), mult(m)
- {
- }
-
- inline WLFloatControl & operator = (F32 val) {
- x = val;
- return *this;
- }
-
- inline operator F32 (void) const {
- return x;
- }
-
- inline void update(LLWLParamSet & params) const {
- params.set(mName, x);
- }
-};
-
-/// WindLight parameter manager class - what controls all the wind light shaders
-class LLWLParamManager : public LLSingleton<LLWLParamManager>
-{
- LLSINGLETON(LLWLParamManager);
- ~LLWLParamManager();
- LOG_CLASS(LLWLParamManager);
-
-public:
- typedef std::list<std::string> preset_name_list_t;
- typedef std::list<LLWLParamKey> preset_key_list_t;
- typedef boost::signals2::signal<void()> preset_list_signal_t;
-
- /// save the parameter presets to file
- void savePreset(const LLWLParamKey key);
-
- /// Set shader uniforms dirty, so they'll update automatically.
- void propagateParameters(void);
-
- /// Update shader uniforms that have changed.
- void updateShaderUniforms(LLGLSLShader * shader);
-
- /// setup the animator to run
- void resetAnimator(F32 curTime, bool run);
-
- /// update information camera dependent parameters
- void update(LLViewerCamera * cam);
-
- /// apply specified day cycle, setting time to noon by default
- bool applyDayCycleParams(const LLSD& params, LLEnvKey::EScope scope, F32 time = 0.5);
-
- /// Apply Default.xml map
- void setDefaultDay();
-
- /// apply specified fixed sky params
- bool applySkyParams(const LLSD& params);
-
- void setDefaultSky();
-
- // get where the light is pointing
- inline LLVector4 getLightDir(void) const;
-
- // get where the light is pointing
- inline LLVector4 getClampedLightDir(void) const;
-
- // get where the light is pointing
- inline LLVector4 getRotatedLightDir(void) const;
-
- /// get the dome's offset
- inline F32 getDomeOffset(void) const;
-
- /// get the radius of the dome
- inline F32 getDomeRadius(void) const;
-
- /// add a param set (preset) to the list
- bool addParamSet(const LLWLParamKey& key, LLWLParamSet& param);
-
- /// add a param set (preset) to the list
- BOOL addParamSet(const LLWLParamKey& key, LLSD const & param);
-
- /// get a param set (preset) from the list
- bool getParamSet(const LLWLParamKey& key, LLWLParamSet& param);
-
- /// check whether the preset is in the list
- bool hasParamSet(const LLWLParamKey& key);
-
- /// set the param in the list with a new param
- bool setParamSet(const LLWLParamKey& key, LLWLParamSet& param);
-
- /// set the param in the list with a new param
- bool setParamSet(const LLWLParamKey& key, LLSD const & param);
-
- /// gets rid of a parameter and any references to it
- /// ignores "delete_from_disk" if the scope is not local
- void removeParamSet(const LLWLParamKey& key, bool delete_from_disk);
-
- /// clear parameter mapping of a given scope
- void clearParamSetsOfScope(LLEnvKey::EScope scope);
-
- /// @return true if the preset comes out of the box
- bool isSystemPreset(const std::string& preset_name) const;
-
- /// @return user and system preset names as a single list
- void getPresetNames(preset_name_list_t& region, preset_name_list_t& user, preset_name_list_t& sys) const;
-
- /// @return user preset names
- void getUserPresetNames(preset_name_list_t& user) const;
-
- /// @return keys of all known presets
- void getPresetKeys(preset_key_list_t& keys) const;
-
- /// Emitted when a preset gets added or deleted.
- boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
-
- /// add all skies in LLSD using the given scope
- void addAllSkies(LLEnvKey::EScope scope, const LLSD& preset_map);
-
- /// refresh region-scope presets
- void refreshRegionPresets(const LLSD& region_sky_presets);
-
- // returns all skies referenced by the current day cycle (in mDay), with their final names
- // side effect: applies changes to all internal structures! (trashes all unreferenced skies in scope, keys in day cycle rescoped to scope, etc.)
- std::map<LLWLParamKey, LLWLParamSet> finalizeFromDayCycle(LLWLParamKey::EScope scope);
-
- // returns all skies in map (intended to be called with output from a finalize)
- static LLSD createSkyMap(std::map<LLWLParamKey, LLWLParamSet> map);
-
- /// escape string in a way different from LLURI::escape()
- static std::string escapeString(const std::string& str);
-
- // helper variables
- LLWLAnimator mAnimator;
-
- /// actual direction of the sun
- LLVector4 mLightDir;
-
- /// light norm adjusted so haze works correctly
- LLVector4 mRotatedLightDir;
-
- /// clamped light norm for shaders that
- /// are adversely affected when the sun goes below the
- /// horizon
- LLVector4 mClampedLightDir;
-
- // list of params and how they're cycled for days
- LLWLDayCycle mDay;
-
- LLWLParamSet mCurParams;
-
- /// Sun Delta Terrain tweak variables.
- F32 mSunDeltaYaw;
- WLFloatControl mWLGamma;
-
- F32 mSceneLightStrength;
-
- /// Atmospherics
- WLColorControl mBlueHorizon;
- WLFloatControl mHazeDensity;
- WLColorControl mBlueDensity;
- WLFloatControl mDensityMult;
- WLFloatControl mHazeHorizon;
- WLFloatControl mMaxAlt;
-
- /// Lighting
- WLColorControl mLightnorm;
- WLColorControl mSunlight;
- WLColorControl mAmbient;
- WLColorControl mGlow;
-
- /// Clouds
- WLColorControl mCloudColor;
- WLColorControl mCloudMain;
- WLFloatControl mCloudCoverage;
- WLColorControl mCloudDetail;
- WLFloatControl mDistanceMult;
- WLFloatControl mCloudScale;
-
- /// sky dome
- F32 mDomeOffset;
- F32 mDomeRadius;
-
-
-private:
-
- friend class LLWLAnimator;
-
- void loadAllPresets();
- void loadPresetsFromDir(const std::string& dir);
- bool loadPreset(const std::string& path);
-
- static std::string getSysDir();
- static std::string getUserDir();
-
- /*virtual*/ void initSingleton();
- // list of all the parameters, listed by name
- std::map<LLWLParamKey, LLWLParamSet> mParamList;
-
- preset_list_signal_t mPresetListChangeSignal;
-};
-
-inline F32 LLWLParamManager::getDomeOffset(void) const
-{
- return mDomeOffset;
-}
-
-inline F32 LLWLParamManager::getDomeRadius(void) const
-{
- return mDomeRadius;
-}
-
-inline LLVector4 LLWLParamManager::getLightDir(void) const
-{
- return mLightDir;
-}
-
-inline LLVector4 LLWLParamManager::getClampedLightDir(void) const
-{
- return mClampedLightDir;
-}
-
-inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const
-{
- return mRotatedLightDir;
-}
-
-#endif
-
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
deleted file mode 100644
index 986f167d8d..0000000000
--- a/indra/newview/llwlparamset.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/**
- * @file llwlparamset.cpp
- * @brief Implementation for the LLWLParamSet class.
- *
- * $LicenseInfo:firstyear=2005&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 "llwlparamset.h"
-#include "llwlanimator.h"
-
-#include "llwlparammanager.h"
-#include "llglslshader.h"
-#include "lluictrlfactory.h"
-#include "llsliderctrl.h"
-#include "pipeline.h"
-
-#include <llgl.h>
-
-#include <sstream>
-
-static LLStaticHashedString sStarBrightness("star_brightness");
-static LLStaticHashedString sPresetNum("preset_num");
-static LLStaticHashedString sSunAngle("sun_angle");
-static LLStaticHashedString sEastAngle("east_angle");
-static LLStaticHashedString sEnableCloudScroll("enable_cloud_scroll");
-static LLStaticHashedString sCloudScrollRate("cloud_scroll_rate");
-static LLStaticHashedString sLightNorm("lightnorm");
-static LLStaticHashedString sCloudDensity("cloud_pos_density1");
-static LLStaticHashedString sCloudScale("cloud_scale");
-static LLStaticHashedString sCloudShadow("cloud_shadow");
-static LLStaticHashedString sDensityMultiplier("density_multiplier");
-static LLStaticHashedString sDistanceMultiplier("distance_multiplier");
-static LLStaticHashedString sHazeDensity("haze_density");
-static LLStaticHashedString sHazeHorizon("haze_horizon");
-static LLStaticHashedString sMaxY("max_y");
-
-LLWLParamSet::LLWLParamSet(void) :
- mName("Unnamed Preset"),
- mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
-{}
-
-static LLTrace::BlockTimerStatHandle FTM_WL_PARAM_UPDATE("WL Param Update");
-
-void LLWLParamSet::update(LLGLSLShader * shader) const
-{
- LL_RECORD_BLOCK_TIME(FTM_WL_PARAM_UPDATE);
- LLSD::map_const_iterator i = mParamValues.beginMap();
- std::vector<LLStaticHashedString>::const_iterator n = mParamHashedNames.begin();
- for(;(i != mParamValues.endMap()) && (n != mParamHashedNames.end());++i, n++)
- {
- const LLStaticHashedString& param = *n;
-
- // check that our pre-hashed names are still tracking the mParamValues map correctly
- //
- llassert(param.String() == i->first);
-
- if (param == sStarBrightness || param == sPresetNum || param == sSunAngle ||
- param == sEastAngle || param == sEnableCloudScroll ||
- param == sCloudScrollRate || param == sLightNorm )
- {
- continue;
- }
-
- if (param == sCloudDensity)
- {
- LLVector4 val;
- val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
- val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
- val.mV[2] = (F32) i->second[2].asReal();
- val.mV[3] = (F32) i->second[3].asReal();
-
- stop_glerror();
- shader->uniform4fv(param, 1, val.mV);
- stop_glerror();
- }
- else if (param == sCloudScale || param == sCloudShadow ||
- param == sDensityMultiplier || param == sDistanceMultiplier ||
- param == sHazeDensity || param == sHazeHorizon ||
- param == sMaxY )
- {
- F32 val = (F32) i->second[0].asReal();
-
- stop_glerror();
- shader->uniform1f(param, val);
- stop_glerror();
- }
- else // param is the uniform name
- {
- // handle all the different cases
- if (i->second.isArray() && i->second.size() == 4)
- {
- LLVector4 val;
-
- val.mV[0] = (F32) i->second[0].asReal();
- val.mV[1] = (F32) i->second[1].asReal();
- val.mV[2] = (F32) i->second[2].asReal();
- val.mV[3] = (F32) i->second[3].asReal();
-
- stop_glerror();
- shader->uniform4fv(param, 1, val.mV);
- stop_glerror();
- }
- else if (i->second.isReal())
- {
- F32 val = (F32) i->second.asReal();
-
- stop_glerror();
- shader->uniform1f(param, val);
- stop_glerror();
- }
- else if (i->second.isInteger())
- {
- S32 val = (S32) i->second.asInteger();
-
- stop_glerror();
- shader->uniform1i(param, val);
- stop_glerror();
- }
- else if (i->second.isBoolean())
- {
- S32 val = (i->second.asBoolean() ? 1 : 0);
-
- stop_glerror();
- shader->uniform1i(param, val);
- stop_glerror();
- }
- }
- }
-
- if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
- {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
- } else {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
- }
-}
-
-void LLWLParamSet::set(const std::string& paramName, float x)
-{
- // handle case where no array
- if(mParamValues[paramName].isReal())
- {
- mParamValues[paramName] = x;
- }
-
- // handle array
- else if(mParamValues[paramName].isArray() &&
- mParamValues[paramName][0].isReal())
- {
- mParamValues[paramName][0] = x;
- }
-}
-
-void LLWLParamSet::set(const std::string& paramName, float x, float y)
-{
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
-}
-
-void LLWLParamSet::set(const std::string& paramName, float x, float y, float z)
-{
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
- mParamValues[paramName][2] = z;
-}
-
-void LLWLParamSet::set(const std::string& paramName, float x, float y, float z, float w)
-{
- mParamValues[paramName][0] = x;
- mParamValues[paramName][1] = y;
- mParamValues[paramName][2] = z;
- mParamValues[paramName][3] = w;
-}
-
-void LLWLParamSet::set(const std::string& paramName, const float * val)
-{
- mParamValues[paramName][0] = val[0];
- mParamValues[paramName][1] = val[1];
- mParamValues[paramName][2] = val[2];
- mParamValues[paramName][3] = val[3];
-}
-
-void LLWLParamSet::set(const std::string& paramName, const LLVector4 & val)
-{
- mParamValues[paramName][0] = val.mV[0];
- mParamValues[paramName][1] = val.mV[1];
- mParamValues[paramName][2] = val.mV[2];
- mParamValues[paramName][3] = val.mV[3];
-}
-
-void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val)
-{
- mParamValues[paramName][0] = val.mV[0];
- mParamValues[paramName][1] = val.mV[1];
- mParamValues[paramName][2] = val.mV[2];
- mParamValues[paramName][3] = val.mV[3];
-}
-
-LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error)
-{
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (!cur_val.isArray())
- {
- error = true;
- return LLVector4(0,0,0,0);
- }
-
- LLVector4 val;
- val.mV[0] = (F32) cur_val[0].asReal();
- val.mV[1] = (F32) cur_val[1].asReal();
- val.mV[2] = (F32) cur_val[2].asReal();
- val.mV[3] = (F32) cur_val[3].asReal();
-
- error = false;
- return val;
-}
-
-F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error)
-{
- // test to see if right type
- LLSD cur_val = mParamValues.get(paramName);
- if (cur_val.isArray() && cur_val.size() != 0)
- {
- error = false;
- return (F32) cur_val[0].asReal();
- }
-
- if(cur_val.isReal())
- {
- error = false;
- return (F32) cur_val.asReal();
- }
-
- error = true;
- return 0;
-}
-
-void LLWLParamSet::setSunAngle(float val)
-{
- // keep range 0 - 2pi
- if(val > F_TWO_PI || val < 0)
- {
- F32 num = val / F_TWO_PI;
- num -= floor(num);
- val = F_TWO_PI * num;
- }
-
- mParamValues["sun_angle"] = val;
-}
-
-
-void LLWLParamSet::setEastAngle(float val)
-{
- // keep range 0 - 2pi
- if(val > F_TWO_PI || val < 0)
- {
- F32 num = val / F_TWO_PI;
- num -= floor(num);
- val = F_TWO_PI * num;
- }
-
- mParamValues["east_angle"] = val;
-}
-
-void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
-{
- // set up the iterators
-
- // keep cloud positions and coverage the same
- /// TODO masking will do this later
- F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
- F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
- F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
- F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
- F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();
-
- LLSD srcVal;
- LLSD destVal;
-
- // Iterate through values
- for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
- {
- // If param exists in both src and dest, set the holder variables, otherwise skip
- if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
- {
- srcVal = src.mParamValues[iter->first];
- destVal = dest.mParamValues[iter->first];
- }
- else
- {
- continue;
- }
-
- if(iter->second.isReal()) // If it's a real, interpolate directly
- {
- iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
- }
- else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those
- && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
- {
- // Actually do interpolation: old value + (difference in values * factor)
- for(int i=0; i < iter->second.size(); ++i)
- {
- // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation
- iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
- }
- }
- else // Else, skip
- {
- continue;
- }
- }
-
- // now mix the extra parameters
- setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
- + weight * (F32) dest.getStarBrightness());
-
- // FIXME: we have established that this assert fails
- // frequently. Someone who understands the code needs to figure
- // out if it matters. In the meantime, disabling the checks so we
- // can stop interfering with other development.
-
- //llassert(src.getSunAngle() >= - F_PI &&
- // src.getSunAngle() <= 3 * F_PI);
- //llassert(dest.getSunAngle() >= - F_PI &&
- // dest.getSunAngle() <= 3 * F_PI);
- //llassert(src.getEastAngle() >= 0 &&
- // src.getEastAngle() <= 4 * F_PI);
- //llassert(dest.getEastAngle() >= 0 &&
- // dest.getEastAngle() <= 4 * F_PI);
-
- // sun angle and east angle require some handling to make sure
- // they go in circles. Yes quaternions would work better.
- F32 srcSunAngle = src.getSunAngle();
- F32 destSunAngle = dest.getSunAngle();
- F32 srcEastAngle = src.getEastAngle();
- F32 destEastAngle = dest.getEastAngle();
-
- if(fabsf(srcSunAngle - destSunAngle) > F_PI)
- {
- if(srcSunAngle > destSunAngle)
- {
- destSunAngle += 2 * F_PI;
- }
- else
- {
- srcSunAngle += 2 * F_PI;
- }
- }
-
- if(fabsf(srcEastAngle - destEastAngle) > F_PI)
- {
- if(srcEastAngle > destEastAngle)
- {
- destEastAngle += 2 * F_PI;
- }
- else
- {
- srcEastAngle += 2 * F_PI;
- }
- }
-
- setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
- setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
-
- // now setup the sun properly
-
- // reset those cloud positions
- mParamValues["cloud_pos_density1"][0] = cloudPos1X;
- mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
- mParamValues["cloud_pos_density2"][0] = cloudPos2X;
- mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
- mParamValues["cloud_shadow"][0] = cloudCover;
-}
-
-void LLWLParamSet::updateCloudScrolling(void)
-{
- static LLTimer s_cloud_timer;
-
- F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();
-
- if(getEnableCloudScrollX())
- {
- mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f);
- }
- if(getEnableCloudScrollY())
- {
- mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f);
- }
-}
-
-void LLWLParamSet::updateHashedNames()
-{
- mParamHashedNames.clear();
- // Iterate through values
- for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
- {
- mParamHashedNames.push_back(LLStaticHashedString(iter->first));
- }
-}
-
diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h
deleted file mode 100644
index 6e5f1d3a4b..0000000000
--- a/indra/newview/llwlparamset.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * @file llwlparamset.h
- * @brief Interface for the LLWLParamSet class.
- *
- * $LicenseInfo:firstyear=2005&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_WLPARAM_SET_H
-#define LL_WLPARAM_SET_H
-
-#include <string>
-#include <map>
-#include <vector>
-
-#include "v4math.h"
-#include "v4color.h"
-#include "llstaticstringtable.h"
-
-class LLWLParamSet;
-class LLGLSLShader;
-
-/// A class representing a set of parameter values for the WindLight shaders.
-class LLWLParamSet {
-
- friend class LLWLParamManager;
-
-public:
- std::string mName;
-
-private:
-
- LLSD mParamValues;
- std::vector<LLStaticHashedString> mParamHashedNames;
-
- float mCloudScrollXOffset, mCloudScrollYOffset;
-
- void updateHashedNames();
-
-public:
-
- LLWLParamSet();
-
- /// Update this set of shader uniforms from the parameter values.
- void update(LLGLSLShader * shader) const;
-
- /// set the total llsd
- void setAll(const LLSD& val);
-
- /// get the total llsd
- const LLSD& getAll();
-
-
- /// Set a float parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The float value to set.
- void set(const std::string& paramName, float x);
-
- /// Set a float2 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- void set(const std::string& paramName, float x, float y);
-
- /// Set a float3 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- /// \param z The z component's value to set.
- void set(const std::string& paramName, float x, float y, float z);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param x The x component's value to set.
- /// \param y The y component's value to set.
- /// \param z The z component's value to set.
- /// \param w The w component's value to set.
- void set(const std::string& paramName, float x, float y, float z, float w);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val An array of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const float * val);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val A struct of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const LLVector4 & val);
-
- /// Set a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param val A struct of the 4 float values to set the parameter to.
- void set(const std::string& paramName, const LLColor4 & val);
-
- /// Get a float4 parameter.
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- LLVector4 getVector(const std::string& paramName, bool& error);
-
- /// Get a float parameter
- /// \param paramName The name of the parameter to set.
- /// \param error A flag to set if it's not the proper return type
- F32 getFloat(const std::string& paramName, bool& error);
-
-
- // specific getters and setters
-
-
- /// set the star's brightness
- /// \param val brightness value
- void setStarBrightness(F32 val);
-
- /// get the star brightness value;
- F32 getStarBrightness();
-
- void setSunAngle(F32 val);
- F32 getSunAngle();
-
- void setEastAngle(F32 val);
- F32 getEastAngle();
-
-
-
- /// set the cloud scroll x enable value
- /// \param val scroll x value
- void setEnableCloudScrollX(bool val);
-
- /// get the scroll x enable value;
- bool getEnableCloudScrollX();
-
- /// set the star's brightness
- /// \param val scroll y bool value
- void setEnableCloudScrollY(bool val);
-
- /// get the scroll enable y value;
- bool getEnableCloudScrollY();
-
- /// set the cloud scroll x enable value
- /// \param val scroll x value
- void setCloudScrollX(F32 val);
-
- /// get the scroll x enable value;
- F32 getCloudScrollX();
-
- /// set the star's brightness
- /// \param val scroll y bool value
- void setCloudScrollY(F32 val);
-
- /// get the scroll enable y value;
- F32 getCloudScrollY();
-
- /// interpolate two parameter sets
- /// \param src The parameter set to start with
- /// \param dest The parameter set to end with
- /// \param weight The amount to interpolate
- void mix(LLWLParamSet& src, LLWLParamSet& dest,
- F32 weight);
-
- void updateCloudScrolling(void);
-};
-
-inline void LLWLParamSet::setAll(const LLSD& val)
-{
- if(val.isMap()) {
- mParamValues = val;
- }
-
- updateHashedNames();
-}
-
-inline const LLSD& LLWLParamSet::getAll()
-{
- return mParamValues;
-}
-
-inline void LLWLParamSet::setStarBrightness(float val) {
- mParamValues["star_brightness"] = val;
-}
-
-inline F32 LLWLParamSet::getStarBrightness() {
- return (F32) mParamValues["star_brightness"].asReal();
-}
-
-inline F32 LLWLParamSet::getSunAngle() {
- return (F32) mParamValues["sun_angle"].asReal();
-}
-
-inline F32 LLWLParamSet::getEastAngle() {
- return (F32) mParamValues["east_angle"].asReal();
-}
-
-
-inline void LLWLParamSet::setEnableCloudScrollX(bool val) {
- mParamValues["enable_cloud_scroll"][0] = val;
-}
-
-inline bool LLWLParamSet::getEnableCloudScrollX() {
- return mParamValues["enable_cloud_scroll"][0].asBoolean();
-}
-
-inline void LLWLParamSet::setEnableCloudScrollY(bool val) {
- mParamValues["enable_cloud_scroll"][1] = val;
-}
-
-inline bool LLWLParamSet::getEnableCloudScrollY() {
- return mParamValues["enable_cloud_scroll"][1].asBoolean();
-}
-
-
-inline void LLWLParamSet::setCloudScrollX(F32 val) {
- mParamValues["cloud_scroll_rate"][0] = val;
-}
-
-inline F32 LLWLParamSet::getCloudScrollX() {
- return (F32) mParamValues["cloud_scroll_rate"][0].asReal();
-}
-
-inline void LLWLParamSet::setCloudScrollY(F32 val) {
- mParamValues["cloud_scroll_rate"][1] = val;
-}
-
-inline F32 LLWLParamSet::getCloudScrollY() {
- return (F32) mParamValues["cloud_scroll_rate"][1].asReal();
-}
-
-
-#endif // LL_WLPARAM_SET_H
-
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 89f5eb86b3..a1a1db35d6 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -730,11 +730,20 @@ void LLWorld::updateRegions(F32 max_update_time)
{
//perform some necessary but very light updates.
(*iter)->lightIdleUpdate();
- }
+ }
+ }
+
+ if(max_time > 0.f)
+ {
+ max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f);
+ }
+ if(max_time > 0.f)
+ {
+ LLViewerRegion::idleCleanup(max_time);
}
sample(sNumActiveCachedObjects, mNumOfActiveCachedObjects);
- }
+}
void LLWorld::clearAllVisibleObjects()
{
@@ -873,6 +882,57 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh
}
}
+void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water)
+{
+ if (!gAgent.getRegion())
+ {
+ return;
+ }
+
+ if (mRegionList.empty())
+ {
+ LL_WARNS() << "No regions!" << LL_ENDL;
+ return;
+ }
+
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ LLVOWater* waterp = regionp->getLand().getWaterObj();
+ if (waterp && waterp->mDrawable)
+ {
+ waterp->mDrawable->setVisible(camera);
+ cull->pushDrawable(waterp->mDrawable);
+ }
+ }
+
+ if (include_void_water)
+ {
+ for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
+ iter != mHoleWaterObjects.end(); ++ iter)
+ {
+ LLVOWater* waterp = (*iter).get();
+ if (waterp && waterp->mDrawable)
+ {
+ waterp->mDrawable->setVisible(camera);
+ cull->pushDrawable(waterp->mDrawable);
+ }
+ }
+ }
+
+ S32 dir;
+ for (dir = 0; dir < 8; dir++)
+ {
+ LLVOWater* waterp = mEdgeWaterObjects[dir];
+ if (waterp && waterp->mDrawable)
+ {
+ waterp->mDrawable->setVisible(camera);
+ cull->pushDrawable(waterp->mDrawable);
+ }
+ }
+}
+
void LLWorld::updateWaterObjects()
{
if (!gAgent.getRegion())
@@ -1157,11 +1217,14 @@ public:
}
};
+static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region");
// disable the circuit to this simulator
// Called in response to "DisableSimulator" message.
void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
-{
- LLHost host = mesgsys->getSender();
+{
+ LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION);
+
+ LLHost host = mesgsys->getSender();
//LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL;
LLWorld::getInstance()->removeRegion(host);
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 993fbfb2cc..98552bc4d1 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -138,6 +138,9 @@ public:
LLViewerTexture *getDefaultWaterTexture();
void updateWaterObjects();
+
+ void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water);
+
void waterHeightRegionInfo(std::string const& sim_name, F32 water_height);
void shiftRegions(const LLVector3& offset);
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 9bc3a2a33b..a6df079223 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1154,7 +1154,7 @@ void LLWorldMapView::drawAvatar(F32 x_pixels,
{
const F32 HEIGHT_THRESHOLD = 7.f;
LLUIImagePtr dot_image = sAvatarLevelImage;
- if (unknown_relative_z)
+ if (unknown_relative_z && llabs(relative_z) > HEIGHT_THRESHOLD)
{
dot_image = sAvatarUnknownImage;
}
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index a2e519a61a..040d0deaf3 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -190,6 +190,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
//LL_INFOS("WorldMap") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LL_INFOS("MAPURL") << "fetching map tile from " << imageurl << LL_ENDL;
+
img->setBoostLevel(LLGLTexture::BOOST_MAP);
// Return the smart pointer
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 7bc8af4a0b..bae615232e 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -43,6 +43,7 @@
// other Linden headers
#include "llerror.h"
+#include "lleventcoro.h"
#include "stringize.h"
#include "llxmlrpctransaction.h"
#include "llsecapi.h"
@@ -100,34 +101,17 @@ public:
{
// from curl.h
// skip the "CURLE_" prefix for each of these strings
-#define def(sym) (mMap[sym] = #sym + 6)
+#define def(sym) (mMap[sym] = &#sym[6])
def(CURLE_OK);
def(CURLE_UNSUPPORTED_PROTOCOL); /* 1 */
def(CURLE_FAILED_INIT); /* 2 */
def(CURLE_URL_MALFORMAT); /* 3 */
- def(CURLE_URL_MALFORMAT_USER); /* 4 - NOT USED */
def(CURLE_COULDNT_RESOLVE_PROXY); /* 5 */
def(CURLE_COULDNT_RESOLVE_HOST); /* 6 */
def(CURLE_COULDNT_CONNECT); /* 7 */
- def(CURLE_FTP_WEIRD_SERVER_REPLY); /* 8 */
- def(CURLE_FTP_ACCESS_DENIED); /* 9 a service was denied by the FTP server
- due to lack of access - when login fails
- this is not returned. */
- def(CURLE_FTP_USER_PASSWORD_INCORRECT); /* 10 - NOT USED */
- def(CURLE_FTP_WEIRD_PASS_REPLY); /* 11 */
- def(CURLE_FTP_WEIRD_USER_REPLY); /* 12 */
- def(CURLE_FTP_WEIRD_PASV_REPLY); /* 13 */
- def(CURLE_FTP_WEIRD_227_FORMAT); /* 14 */
- def(CURLE_FTP_CANT_GET_HOST); /* 15 */
- def(CURLE_FTP_CANT_RECONNECT); /* 16 */
- def(CURLE_FTP_COULDNT_SET_BINARY); /* 17 */
def(CURLE_PARTIAL_FILE); /* 18 */
- def(CURLE_FTP_COULDNT_RETR_FILE); /* 19 */
- def(CURLE_FTP_WRITE_ERROR); /* 20 */
- def(CURLE_FTP_QUOTE_ERROR); /* 21 */
def(CURLE_HTTP_RETURNED_ERROR); /* 22 */
def(CURLE_WRITE_ERROR); /* 23 */
- def(CURLE_MALFORMAT_USER); /* 24 - NOT USED */
def(CURLE_UPLOAD_FAILED); /* 25 - failed upload "command" */
def(CURLE_READ_ERROR); /* 26 - could open/read from file */
def(CURLE_OUT_OF_MEMORY); /* 27 */
@@ -135,29 +119,18 @@ public:
instead of a memory allocation error if CURL_DOES_CONVERSIONS
is defined
*/
- def(CURLE_OPERATION_TIMEOUTED); /* 28 - the timeout time was reached */
- def(CURLE_FTP_COULDNT_SET_ASCII); /* 29 - TYPE A failed */
- def(CURLE_FTP_PORT_FAILED); /* 30 - FTP PORT operation failed */
- def(CURLE_FTP_COULDNT_USE_REST); /* 31 - the REST command failed */
- def(CURLE_FTP_COULDNT_GET_SIZE); /* 32 - the SIZE command failed */
+ def(CURLE_OPERATION_TIMEDOUT); /* 28 - the timeout time was reached */
def(CURLE_HTTP_RANGE_ERROR); /* 33 - RANGE "command" didn't work */
def(CURLE_HTTP_POST_ERROR); /* 34 */
def(CURLE_SSL_CONNECT_ERROR); /* 35 - wrong when connecting with SSL */
def(CURLE_BAD_DOWNLOAD_RESUME); /* 36 - couldn't resume download */
def(CURLE_FILE_COULDNT_READ_FILE); /* 37 */
- def(CURLE_LDAP_CANNOT_BIND); /* 38 */
- def(CURLE_LDAP_SEARCH_FAILED); /* 39 */
def(CURLE_LIBRARY_NOT_FOUND); /* 40 */
def(CURLE_FUNCTION_NOT_FOUND); /* 41 */
def(CURLE_ABORTED_BY_CALLBACK); /* 42 */
def(CURLE_BAD_FUNCTION_ARGUMENT); /* 43 */
- def(CURLE_BAD_CALLING_ORDER); /* 44 - NOT USED */
def(CURLE_INTERFACE_FAILED); /* 45 - CURLOPT_INTERFACE failed */
- def(CURLE_BAD_PASSWORD_ENTERED); /* 46 - NOT USED */
def(CURLE_TOO_MANY_REDIRECTS ); /* 47 - catch endless re-direct loops */
- def(CURLE_UNKNOWN_TELNET_OPTION); /* 48 - User specified an unknown option */
- def(CURLE_TELNET_OPTION_SYNTAX ); /* 49 - Malformed telnet option */
- def(CURLE_OBSOLETE); /* 50 - NOT USED */
def(CURLE_SSL_PEER_CERTIFICATE); /* 51 - peer's certificate wasn't ok */
def(CURLE_GOT_NOTHING); /* 52 - when this is a specific error */
def(CURLE_SSL_ENGINE_NOTFOUND); /* 53 - SSL crypto engine not found */
@@ -165,26 +138,19 @@ public:
default */
def(CURLE_SEND_ERROR); /* 55 - failed sending network data */
def(CURLE_RECV_ERROR); /* 56 - failure in receiving network data */
- def(CURLE_SHARE_IN_USE); /* 57 - share is in use */
+
def(CURLE_SSL_CERTPROBLEM); /* 58 - problem with the local certificate */
def(CURLE_SSL_CIPHER); /* 59 - couldn't use specified cipher */
def(CURLE_SSL_CACERT); /* 60 - problem with the CA cert (path?) */
def(CURLE_BAD_CONTENT_ENCODING); /* 61 - Unrecognized transfer encoding */
- def(CURLE_LDAP_INVALID_URL); /* 62 - Invalid LDAP URL */
+
def(CURLE_FILESIZE_EXCEEDED); /* 63 - Maximum file size exceeded */
- def(CURLE_FTP_SSL_FAILED); /* 64 - Requested FTP SSL level failed */
+
def(CURLE_SEND_FAIL_REWIND); /* 65 - Sending the data requires a rewind
that failed */
def(CURLE_SSL_ENGINE_INITFAILED); /* 66 - failed to initialise ENGINE */
def(CURLE_LOGIN_DENIED); /* 67 - user); password or similar was not
accepted and we failed to login */
- def(CURLE_TFTP_NOTFOUND); /* 68 - file not found on server */
- def(CURLE_TFTP_PERM); /* 69 - permission problem on server */
- def(CURLE_TFTP_DISKFULL); /* 70 - out of disk space on server */
- def(CURLE_TFTP_ILLEGAL); /* 71 - Illegal TFTP operation */
- def(CURLE_TFTP_UNKNOWNID); /* 72 - Unknown transfer ID */
- def(CURLE_TFTP_EXISTS); /* 73 - File already exists */
- def(CURLE_TFTP_NOSUCHUSER); /* 74 - No such user */
def(CURLE_CONV_FAILED); /* 75 - conversion failed */
def(CURLE_CONV_REQD); /* 76 - caller must register conversion
callbacks using curl_easy_setopt options
@@ -401,6 +367,8 @@ public:
// whether successful or not, send reply on requested LLEventPump
replyPump.post(data);
+ // need to wake up the loginCoro now
+ llcoro::suspend();
// Because mTransaction is a boost::scoped_ptr, deleting this object
// frees our LLXMLRPCTransaction object.
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 8e2539606b..32c8ce66a0 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -240,16 +240,16 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle,
if (!status)
{
+ mImpl->setHttpStatus(status);
+ LLSD errordata = status.getErrorData();
+ mImpl->mErrorCertData = errordata;
+
if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) &&
(status.toULong() != CURLE_SSL_CACERT))
{
// if we have a curl error that's not already been handled
- // (a non cert error), then generate the error message as
+ // (a non cert error), then generate the warning message as
// appropriate
- mImpl->setHttpStatus(status);
- LLSD errordata = status.getErrorData();
- mImpl->mErrorCertData = errordata;
-
LL_WARNS() << "LLXMLRPCTransaction error "
<< status.toHex() << ": " << status.toString() << LL_ENDL;
LL_WARNS() << "LLXMLRPCTransaction request URI: "
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bc5b3534c7..cd1b9c7c69 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -88,6 +88,7 @@
#include "llvocache.h"
#include "llvoground.h"
#include "llvosky.h"
+#include "llvowlsky.h"
#include "llvotree.h"
#include "llvovolume.h"
#include "llvosurfacepatch.h"
@@ -100,8 +101,6 @@
#include "llviewerstats.h"
#include "llviewerjoystick.h"
#include "llviewerdisplay.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llspatialpartition.h"
#include "llmutelist.h"
#include "lltoolpie.h"
@@ -116,6 +115,9 @@
#include "llprogressview.h"
#include "llcleanup.h"
+#include "llenvironment.h"
+#include "llsettingsvo.h"
+
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
//#define DEBUG_INDICES
@@ -127,11 +129,20 @@
//
#define MATERIALS_IN_REFLECTIONS 0
+// 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_TERRAIN = 1;
+ const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
+ const S32 WATER_REFLECT_AVATARS = 3;
+ const S32 WATER_REFLECT_EVERYTHING = 4;
+
bool gShiftFrame = false;
//cached settings
bool LLPipeline::RenderAvatarVP;
-bool LLPipeline::VertexShaderEnable;
bool LLPipeline::WindLightUseAtmosShaders;
bool LLPipeline::RenderDeferred;
F32 LLPipeline::RenderDeferredSunWash;
@@ -187,6 +198,7 @@ F32 LLPipeline::RenderShadowOffset;
F32 LLPipeline::RenderShadowBias;
F32 LLPipeline::RenderSpotShadowOffset;
F32 LLPipeline::RenderSpotShadowBias;
+LLDrawable* LLPipeline::RenderSpotLight = nullptr;
F32 LLPipeline::RenderEdgeDepthCutoff;
F32 LLPipeline::RenderEdgeNormCutoff;
LLVector3 LLPipeline::RenderShadowGaussian;
@@ -209,6 +221,7 @@ LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
+const F32 DEFERRED_LIGHT_FALLOFF = 0.5f;
const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
extern S32 gBoxFrame;
@@ -253,6 +266,11 @@ LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline");
LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy");
LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD("HUD");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D("3D");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D("2D");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT("Debug Text");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON("Scene Mon");
static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables");
static LLTrace::BlockTimerStatHandle FTM_STATESORT_POSTSORT("Post Sort");
@@ -298,62 +316,6 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
-glh::matrix4f glh_copy_matrix(F32* src)
-{
- glh::matrix4f ret;
- ret.set_value(src);
- return ret;
-}
-
-glh::matrix4f glh_get_current_modelview()
-{
- return glh_copy_matrix(gGLModelView);
-}
-
-glh::matrix4f glh_get_current_projection()
-{
- return glh_copy_matrix(gGLProjection);
-}
-
-glh::matrix4f glh_get_last_modelview()
-{
- return glh_copy_matrix(gGLLastModelView);
-}
-
-glh::matrix4f glh_get_last_projection()
-{
- return glh_copy_matrix(gGLLastProjection);
-}
-
-void glh_copy_matrix(const glh::matrix4f& src, F32* dst)
-{
- for (U32 i = 0; i < 16; i++)
- {
- dst[i] = src.m[i];
- }
-}
-
-void glh_set_current_modelview(const glh::matrix4f& mat)
-{
- glh_copy_matrix(mat, gGLModelView);
-}
-
-void glh_set_current_projection(glh::matrix4f& mat)
-{
- glh_copy_matrix(mat, gGLProjection);
-}
-
-glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar)
-{
- glh::matrix4f ret(
- 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left),
- 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom),
- 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear),
- 0.f, 0.f, 0.f, 1.f);
-
- return ret;
-}
-
void display_update_camera();
//----------------------------------------
@@ -377,6 +339,7 @@ bool LLPipeline::sDelayVBUpdate = true;
bool LLPipeline::sAutoMaskAlphaDeferred = true;
bool LLPipeline::sAutoMaskAlphaNonDeferred = false;
bool LLPipeline::sDisableShaders = false;
+bool LLPipeline::sRenderTransparentWater = true;
bool LLPipeline::sRenderBump = true;
bool LLPipeline::sBakeSunlight = false;
bool LLPipeline::sNoAlpha = false;
@@ -386,6 +349,7 @@ bool LLPipeline::sShadowRender = false;
bool LLPipeline::sWaterReflections = false;
bool LLPipeline::sRenderGlow = false;
bool LLPipeline::sReflectionRender = false;
+bool LLPipeline::sDistortionRender = false;
bool LLPipeline::sImpostorRender = false;
bool LLPipeline::sImpostorRenderAlphaDepthPass = false;
bool LLPipeline::sUnderWaterRender = false;
@@ -394,10 +358,10 @@ bool LLPipeline::sRenderFrameTest = false;
bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
-bool LLPipeline::sMemAllocationThrottled = false;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
bool LLPipeline::sRenderingHUDs;
+F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
// EventHost API LLPipeline listener.
static LLPipelineListener sPipelineListener;
@@ -456,6 +420,11 @@ LLPipeline::LLPipeline() :
mNoiseMap = 0;
mTrueNoiseMap = 0;
mLightFunc = 0;
+
+ for(U32 i = 0; i < 8; i++)
+ {
+ mHWLightColors[i] = LLColor4::black;
+ }
}
void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
@@ -572,7 +541,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
connectRefreshCachedSettingsSafe("UseOcclusion");
- connectRefreshCachedSettingsSafe("VertexShaderEnable");
connectRefreshCachedSettingsSafe("RenderAvatarVP");
connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
connectRefreshCachedSettingsSafe("RenderDeferred");
@@ -759,22 +727,21 @@ void LLPipeline::destroyGL()
static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
-//static
-void LLPipeline::throttleNewMemoryAllocation(bool disable)
+void LLPipeline::requestResizeScreenTexture()
{
- if(sMemAllocationThrottled != disable)
- {
- sMemAllocationThrottled = disable ;
+ gResizeScreenTexture = TRUE;
+}
- if(sMemAllocationThrottled)
- {
- //send out notification
- LLNotification::Params params("LowMemory");
- LLNotifications::instance().add(params);
+void LLPipeline::requestResizeShadowTexture()
+{
+ gResizeShadowTexture = TRUE;
+}
- //release some memory.
- }
- }
+void LLPipeline::resizeShadowTexture()
+{
+ releaseShadowTargets();
+ allocateShadowBuffer(mScreenWidth, mScreenHeight);
+ gResizeShadowTexture = FALSE;
}
void LLPipeline::resizeScreenTexture()
@@ -785,25 +752,14 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
{
releaseScreenBuffers();
- if (!allocateScreenBuffer(resX,resY))
- {
-#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE
- //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();
-
+ releaseShadowTargets();
+ allocateScreenBuffer(resX,resY);
+ gResizeScreenTexture = FALSE;
}
-#endif
}
- }
- }
}
void LLPipeline::allocatePhysicsBuffer()
@@ -973,23 +929,78 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mDeferredLight.release();
}
- F32 scale = RenderShadowResolutionScale;
+ allocateShadowBuffer(resX, resY);
+
+ //HACK make screenbuffer allocations start failing after 30 seconds
+ if (gSavedSettings.getBOOL("SimulateFBOFailure"))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ mDeferredLight.release();
+
+ releaseShadowTargets();
+
+ 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();
+
+ if (!mScreen.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();
+
+ return true;
+}
+
+// must be even to avoid a stripe in the horizontal shadow blur
+inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0xF; }
+
+bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
+{
+ refreshCachedSettings();
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ S32 shadow_detail = RenderShadowDetail;
+
+ 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);
if (shadow_detail > 0)
{ //allocate 4 sun shadow maps
- U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur
for (U32 i = 0; i < 4; i++)
{
- if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
- if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ if (!mShadow[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))
+ {
+ return false;
+ }
}
}
else
{
for (U32 i = 0; i < 4; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
}
@@ -999,83 +1010,57 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
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, height, 0, TRUE, FALSE)) return false;
- if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
- }
- }
- else
+ if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
{
- for (U32 i = 4; i < 6; i++)
- {
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ return false;
}
- }
-
- //HACK make screenbuffer allocations start failing after 30 seconds
- if (gSavedSettings.getBOOL("SimulateFBOFailure"))
+ if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))
{
return false;
}
}
+ }
else
{
- mDeferredLight.release();
-
- for (U32 i = 0; i < 6; i++)
+ for (U32 i = 4; i < 6; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
- 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();
-
- if (!mScreen.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();
-
return true;
}
//static
+void LLPipeline::updateRenderTransparentWater()
+{
+ sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
+}
+
+//static
void LLPipeline::updateRenderBump()
{
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
}
-//static
+// static
void LLPipeline::updateRenderDeferred()
{
- bool deferred = (bool(RenderDeferred &&
- LLRenderTarget::sUseFBO &&
- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- LLPipeline::sRenderBump &&
- VertexShaderEnable &&
- RenderAvatarVP &&
- WindLightUseAtmosShaders)) &&
- !gUseWireframe;
-
- sRenderDeferred = deferred;
- if (deferred)
- { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all
- sRenderGlow = true;
- }
+ sRenderDeferred = !gUseWireframe &&
+ RenderDeferred &&
+ LLRenderTarget::sUseFBO &&
+ LLPipeline::sRenderBump &&
+ LLPipeline::sRenderTransparentWater &&
+ RenderAvatarVP &&
+ WindLightUseAtmosShaders &&
+ (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
}
-//static
+// static
void LLPipeline::refreshCachedSettings()
{
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
@@ -1092,7 +1077,6 @@ void LLPipeline::refreshCachedSettings()
&& gSavedSettings.getBOOL("UseOcclusion")
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
- VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable");
RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
@@ -1167,7 +1151,7 @@ void LLPipeline::refreshCachedSettings()
CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
-
+ RenderSpotLight = nullptr;
updateRenderDeferred();
}
@@ -1191,6 +1175,7 @@ void LLPipeline::releaseGLBuffers()
mWaterRef.release();
mWaterDis.release();
+ mBake.release();
mHighlight.release();
for (U32 i = 0; i < 3; i++)
@@ -1213,6 +1198,11 @@ void LLPipeline::releaseLUTBuffers()
}
}
+void LLPipeline::releaseShadowBuffers()
+{
+ releaseShadowTargets();
+}
+
void LLPipeline::releaseScreenBuffers()
{
mUIScreen.release();
@@ -1223,72 +1213,59 @@ void LLPipeline::releaseScreenBuffers()
mDeferredDepth.release();
mDeferredLight.release();
mOcclusionDepth.release();
+}
+
+void LLPipeline::releaseShadowTarget(U32 index)
+{
+ mShadow[index].release();
+ mShadowOcclusion[index].release();
+}
+
+void LLPipeline::releaseShadowTargets()
+{
for (U32 i = 0; i < 6; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
}
-
void LLPipeline::createGLBuffers()
{
stop_glerror();
assertInitialized();
updateRenderDeferred();
-
- bool materials_in_water = false;
-
-#if MATERIALS_IN_REFLECTIONS
- materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
-#endif
-
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
-
- // Set up SRGB targets if we're doing deferred-path reflection rendering
- //
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
- //always use FBO for mWaterDis so it can be used for avatar texture bakes
- mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
- }
- else
- {
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
- //always use FBO for mWaterDis so it can be used for avatar texture bakes
- mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
- }
+ mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
}
+ // Use FBO for bake tex
+ mBake.allocate(512, 512, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, true); // SL-12781 Build > Upload > Model; 3D Preview
+
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
stop_glerror();
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
-
- if (LLPipeline::sRenderGlow)
- { //screen space glow buffers
- const U32 glow_res = llmax(1,
- llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
- for (U32 i = 0; i < 3; i++)
- {
- mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
- }
+ // allocate screen space glow buffers
+ const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
+ for (U32 i = 0; i < 3; i++)
+ {
+ mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE);
+ }
- allocateScreenBuffer(resX,resY);
- mScreenWidth = 0;
- mScreenHeight = 0;
- }
-
- if (sRenderDeferred)
- {
+ allocateScreenBuffer(resX, resY);
+ mScreenWidth = 0;
+ mScreenHeight = 0;
+
+ if (sRenderDeferred)
+ {
if (!mNoiseMap)
{
const U32 noiseRes = 128;
@@ -1416,12 +1393,9 @@ void LLPipeline::restoreGL()
bool LLPipeline::canUseVertexShaders()
{
- static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable";
-
if (sDisableShaders ||
!gGLManager.mHasVertexShader ||
!gGLManager.mHasFragmentShader ||
- !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) ||
(assertInitialized() && mVertexShadersLoaded != 1) )
{
return false;
@@ -1436,13 +1410,13 @@ bool LLPipeline::canUseWindLightShaders() const
{
return (!LLPipeline::sDisableShaders &&
gWLSkyProgram.mProgramObject != 0 &&
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
+ LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
}
bool LLPipeline::canUseWindLightShadersOnObjects() const
{
return (canUseWindLightShaders()
- && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
+ && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
}
bool LLPipeline::canUseAntiAliasing() const
@@ -1471,7 +1445,7 @@ void LLPipeline::enableShadows(const bool enable_shadows)
S32 LLPipeline::getMaxLightingDetail() const
{
- /*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
+ /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
{
return 3;
}
@@ -1624,6 +1598,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
break;
case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
break; // Do nothing
case LLDrawPool::POOL_SKY:
@@ -2010,7 +1985,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
if (done)
{
- if (drawablep->isRoot())
+ if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE))
{
drawablep->makeStatic();
}
@@ -2158,7 +2133,8 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- if (drawable == (LLDrawable*)(*i)->getDrawable())
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
+ if (drawable == drawablep)
{
LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL;
}
@@ -2299,7 +2275,7 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info)
void LLPipeline::checkReferences(LLSpatialGroup* group)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2409,15 +2385,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
sCull->clear();
- bool to_texture = LLPipeline::sUseOcclusion > 1 &&
- !hasRenderType(LLPipeline::RENDER_TYPE_HUD) &&
- LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
- gPipeline.canUseVertexShaders() &&
- sRenderGlow;
+ bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.canUseVertexShaders();
if (to_texture)
{
- if (LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
mOcclusionDepth.bindTarget();
}
@@ -2444,38 +2416,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling)
- LLViewerRegion* region = gAgent.getRegion();
- LLPlane plane;
-
- if (planep)
- {
- plane = *planep;
- }
- else
- {
- if (region)
- {
- LLVector3 pnorm;
- F32 height = region->getWaterHeight();
- if (water_clip < 0)
- { //camera is above water, clip plane points up
- pnorm.setVec(0,0,1);
- plane.setVec(pnorm, -height);
- }
- else if (water_clip > 0)
- { //camera is below water, clip plane points down
- pnorm = LLVector3(0,0,-1);
- plane.setVec(pnorm, height);
- }
- }
- }
-
- glh::matrix4f modelview = glh_get_last_modelview();
- glh::matrix4f proj = glh_get_last_projection();
- LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender);
-
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bool bound_shader = false;
@@ -2495,19 +2435,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
+ if (!sReflectionRender)
+ {
+ camera.disableUserClipPlane();
+ }
+
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
LLViewerRegion* region = *iter;
- if (water_clip != 0)
- {
- LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight());
- camera.setUserClipPlane(plane);
- }
- else
- {
- camera.disableUserClipPlane();
- }
for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
@@ -2526,6 +2462,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if(vo_part)
{
bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe && 0 > water_clip /* && !gViewerWindow->getProgressView()->getVisible()*/;
+ do_occlusion_cull &= !sReflectionRender;
vo_part->cull(camera, do_occlusion_cull);
}
}
@@ -2535,8 +2472,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
gOcclusionCubeProgram.unbind();
}
- camera.disableUserClipPlane();
-
if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
gSky.mVOSkyp.notNull() &&
gSky.mVOSkyp->mDrawable.notNull())
@@ -2558,6 +2493,22 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
}
+ if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
+ gPipeline.canUseWindLightShaders() &&
+ gSky.mVOWLSkyp.notNull() &&
+ gSky.mVOWLSkyp->mDrawable.notNull())
+ {
+ gSky.mVOWLSkyp->mDrawable->setVisible(camera);
+ sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable);
+ }
+
+ bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER));
+
+ if (render_water)
+ {
+ LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
+ }
+
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -2570,7 +2521,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
mOcclusionDepth.flush();
}
@@ -3123,9 +3074,10 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
if (vobj) // this test may not be needed, see above
{
LLVOAvatar* av = vobj->asAvatar();
- if (av && (av->isImpostor()
- || av->isInMuteList()
- || (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) ))
+ if (av &&
+ ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass
+ || av->isInMuteList()
+ || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) ))
{
return;
}
@@ -3401,6 +3353,7 @@ static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order");
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_GROUND,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_TREE,
@@ -3432,7 +3385,8 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
group->setVisible();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- markVisible((LLDrawable*)(*i)->getDrawable(), camera);
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
+ markVisible(drawablep, camera);
}
if (!sDelayVBUpdate)
@@ -3520,7 +3474,8 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- stateSort((LLDrawable*)(*i)->getDrawable(), camera);
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
+ stateSort(drawablep, camera);
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3549,6 +3504,14 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
return;
}
+ // SL-11353
+ // ignore our own geo when rendering spotlight shadowmaps...
+ //
+ if (RenderSpotLight && drawablep == RenderSpotLight)
+ {
+ return;
+ }
+
if (LLSelectMgr::getInstance()->mHideSelectedObjects)
{
if (drawablep->getVObj().notNull() &&
@@ -4062,6 +4025,7 @@ void LLPipeline::postSort(LLCamera& camera)
void render_hud_elements()
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
LLGLDisable fog(GL_FOG);
@@ -4139,12 +4103,13 @@ void LLPipeline::renderHighlights()
glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- if (canUseVertexShaders())
+ gGL.setColorMask(false, false);
+
+ if (LLGLSLShader::sNoFixedFunction)
{
gHighlightProgram.bind();
}
- gGL.setColorMask(false, false);
for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter)
{
renderHighlight(iter->mItem->getVObj(), 1.f);
@@ -4226,7 +4191,7 @@ void LLPipeline::renderHighlights()
//gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4273,7 +4238,7 @@ void LLPipeline::renderHighlights()
// have touch-handlers.
mHighlightFaces.clear();
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
{
gHighlightProgram.unbind();
}
@@ -4282,7 +4247,7 @@ void LLPipeline::renderHighlights()
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
{
color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightNormalProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4303,7 +4268,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightNormalProgram.unbind();
}
@@ -4312,7 +4277,7 @@ void LLPipeline::renderHighlights()
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
{
color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightSpecularProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4333,7 +4298,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightSpecularProgram.unbind();
}
@@ -4560,6 +4525,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
// Render debugging beacons.
gObjectList.renderObjectBeacons();
gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
}
else
{
@@ -4680,6 +4646,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
}
gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
gGL.setColorMask(true, false);
@@ -4766,16 +4733,16 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
}
gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
if (occlude)
{
occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
doOcclusion(camera);
gGLLastMatrix = NULL;
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
}
}
@@ -5799,6 +5766,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
break;
case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
break; // Do nothing
case LLDrawPool::POOL_SKY:
@@ -5947,6 +5915,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
break;
case LLDrawPool::POOL_AVATAR:
+ case LLDrawPool::POOL_CONTROL_AV:
break; // Do nothing
case LLDrawPool::POOL_SKY:
@@ -5990,6 +5959,12 @@ void LLPipeline::setupAvatarLights(bool for_edit)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ bool sun_up = environment.getIsSunUp();
+
+
if (for_edit)
{
LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
@@ -6003,13 +5978,6 @@ void LLPipeline::setupAvatarLights(bool for_edit)
LLLightState* light = gGL.getLight(1);
- if (LLPipeline::sRenderDeferred)
- {
- /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f);
- diffuse.mV[1] = powf(diffuse.mV[1], 2.2f);
- diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/
- }
-
mHWLightColors[1] = diffuse;
light->setDiffuse(diffuse);
@@ -6024,12 +5992,14 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
{
- LLVector3 opposite_pos = -1.f * mSunDir;
- LLVector3 orthog_light_pos = mSunDir % LLVector3::z_axis;
+ LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir);
+ LLVector3 opposite_pos = -light_dir;
+ LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
backlight_pos.normalize();
- LLColor4 light_diffuse = mSunDiffuse;
+ LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse;
+
LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
F32 max_component = 0.001f;
for (S32 i = 0; i < 3; i++)
@@ -6040,7 +6010,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
}
F32 backlight_mag;
- if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
+ if (LLEnvironment::instance().getIsSunUp())
{
backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
}
@@ -6050,13 +6020,6 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
backlight_diffuse *= backlight_mag / max_component;
- if (LLPipeline::sRenderDeferred)
- {
- /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f);
- backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f);
- backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/
- }
-
mHWLightColors[1] = backlight_diffuse;
LLLightState* light = gGL.getLight(1);
@@ -6090,25 +6053,18 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
{
return max_dist;
}
- F32 radius = light->getLightRadius();
bool selected = light->isSelected();
- LLVector3 dpos = light->getRenderPosition() - cam_pos;
- F32 dist2 = dpos.lengthSquared();
- if (!selected && dist2 > (max_dist + radius)*(max_dist + radius))
- {
- return max_dist;
- }
- F32 dist = (F32) sqrt(dist2);
- dist *= 1.f / inten;
- dist -= radius;
if (selected)
{
- dist -= 10000.f; // selected lights get highest priority
+ return 0.f; // selected lights get highest priority
}
+ F32 radius = light->getLightRadius();
+ F32 dist = dist_vec(light->getRenderPosition(), cam_pos);
+ dist = llmax(dist - radius, 0.f);
if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
{
// moving lights get a little higher priority (too much causes artifacts)
- dist -= light->getLightRadius()*0.25f;
+ dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
}
return dist;
}
@@ -6127,13 +6083,18 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// mNearbyLight (and all light_set_t's) are sorted such that
// begin() == the closest light and rbegin() == the farthest light
const S32 MAX_LOCAL_LIGHTS = 6;
-// LLVector3 cam_pos = gAgent.getCameraPositionAgent();
- LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
- camera.getOrigin() :
- gAgent.getPositionAgent();
-
- F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad
+ LLVector3 cam_pos = camera.getOrigin();
+ F32 max_dist;
+ if (LLPipeline::sRenderDeferred)
+ {
+ max_dist = RenderFarClip;
+ }
+ else
+ {
+ max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f);
+ }
+
// UPDATE THE EXISTING NEARBY LIGHTS
light_set_t cur_nearby_lights;
for (light_set_t::iterator iter = mNearbyLights.begin();
@@ -6167,8 +6128,38 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
- F32 dist = calc_light_dist(volight, cam_pos, max_dist);
- cur_nearby_lights.insert(Light(drawable, dist, light->fade));
+ F32 dist = calc_light_dist(volight, cam_pos, max_dist);
+ F32 fade = light->fade;
+ // actual fade gets decreased/increased by setupHWLights
+ // light->fade value is 'time'.
+ // >=0 and light will become visible as value increases
+ // <0 and light will fade out
+ if (dist < max_dist)
+ {
+ if (fade < 0)
+ {
+ // mark light to fade in
+ // if fade was -LIGHT_FADE_TIME - it was fully invisible
+ // if fade -0 - it was fully visible
+ // visibility goes up from 0 to LIGHT_FADE_TIME.
+ fade += LIGHT_FADE_TIME;
+ }
+ }
+ else
+ {
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ if (fade >= LIGHT_FADE_TIME)
+ {
+ fade = -0.0001f; // was fully visible
+ }
+ else if (fade >= 0)
+ {
+ // 0.75 visible light should stay 0.75 visible, but should reverse direction
+ fade -= LIGHT_FADE_TIME;
+ }
+ }
+ cur_nearby_lights.insert(Light(drawable, dist, fade));
}
mNearbyLights = cur_nearby_lights;
@@ -6187,17 +6178,23 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
continue; // no lighting from HUD objects
}
- F32 dist = calc_light_dist(light, cam_pos, max_dist);
- if (dist >= max_dist)
+ if (!sRenderAttachedLights && light && light->isAttachment())
{
continue;
}
- if (!sRenderAttachedLights && light && light->isAttachment())
+ LLVOAvatar * av = light->getAvatar();
+ if (av && (av->isTooComplex() || av->isInMuteList()))
+ {
+ // avatars that are already in the list will be removed by removeMutedAVsLights
+ continue;
+ }
+ F32 dist = calc_light_dist(light, cam_pos, max_dist);
+ if (dist >= max_dist)
{
continue;
}
new_nearby_lights.insert(Light(drawable, dist, 0.f));
- if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
+ if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
{
new_nearby_lights.erase(--new_nearby_lights.end());
const Light& last = *new_nearby_lights.rbegin();
@@ -6210,7 +6207,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
iter != new_nearby_lights.end(); iter++)
{
const Light* light = &(*iter);
- if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
+ if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
{
mNearbyLights.insert(*light);
((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
@@ -6223,10 +6220,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
if (light->dist < farthest_light->dist)
{
- if (farthest_light->fade >= 0.f)
- {
- farthest_light->fade = -(gFrameIntervalSeconds.value());
- }
+ // mark light to fade out
+ // visibility goes down from -0 to -LIGHT_FADE_TIME.
+ //
+ // This is a mess, but for now it needs to be in sync
+ // with fade code above. Ex: code above detects distance < max,
+ // sets fade time to positive, this code then detects closer
+ // lights and sets fade time negative, fully compensating
+ // for the code above
+ if (farthest_light->fade >= LIGHT_FADE_TIME)
+ {
+ farthest_light->fade = -0.0001f; // was fully visible
+ }
+ else if (farthest_light->fade >= 0)
+ {
+ farthest_light->fade -= LIGHT_FADE_TIME;
+ }
}
else
{
@@ -6249,26 +6258,31 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
{
assertInitialized();
- // Ambient
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
if (!LLGLSLShader::sNoFixedFunction)
{
gGL.syncMatrices();
- LLColor4 ambient = gSky.getTotalAmbientColor();
- gGL.setAmbientLightColor(ambient);
}
+ // Ambient
+ LLColor4 ambient = psky->getTotalAmbient();
+ gGL.setAmbientLightColor(ambient);
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+
// Light 0 = Sun or Moon (All objects)
{
- if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
- {
- mSunDir.setVec(gSky.getSunDirection());
- mSunDiffuse.setVec(gSky.getSunDiffuseColor());
- }
- else
- {
- mSunDir.setVec(gSky.getMoonDirection());
- mSunDiffuse.setVec(gSky.getMoonDiffuseColor());
- }
+ LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
+ LLVector4 moon_dir(environment.getMoonDirection(), 0.0f);
+
+ mSunDir.setVec(sun_dir);
+ mMoonDir.setVec(moon_dir);
+
+ mSunDiffuse.setVec(psky->getSunlightColor());
+ mMoonDiffuse.setVec(psky->getMoonlightColor());
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
if (max_color > 1.f)
@@ -6277,22 +6291,33 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
mSunDiffuse.clamp();
- LLVector4 light_pos(mSunDir, 0.0f);
- LLColor4 light_diffuse = mSunDiffuse;
+ max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]);
+ if (max_color > 1.f)
+ {
+ mMoonDiffuse *= 1.f/max_color;
+ }
+ mMoonDiffuse.clamp();
- if (LLPipeline::sRenderDeferred)
+ // prevent underlighting from having neither lightsource facing us
+ if (!sun_up && !moon_up)
{
- /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
- light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
- light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ mSunDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0));
+ mMoonDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0));
+ mSunDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0));
+ mMoonDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0));
}
- mHWLightColors[0] = light_diffuse;
+ LLVector4 light_dir = sun_up ? mSunDir : mMoonDir;
+
+ mHWLightColors[0] = sun_up ? mSunDiffuse : mMoonDiffuse;
LLLightState* light = gGL.getLight(0);
- light->setPosition(light_pos);
- light->setDiffuse(light_diffuse);
- light->setAmbient(LLColor4::black);
+ light->setPosition(light_dir);
+
+ light->setSunPrimary(sun_up);
+ light->setDiffuse(mHWLightColors[0]);
+ light->setDiffuseB(mMoonDiffuse);
+ light->setAmbient(psky->getTotalAmbient());
light->setSpecular(LLColor4::black);
light->setConstantAttenuation(1.f);
light->setLinearAttenuation(0.f);
@@ -6321,12 +6346,22 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
{
continue;
}
+
+ if (light->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
if (drawable->isState(LLDrawable::ACTIVE))
{
mLightMovingMask |= (1<<cur_light);
}
- LLColor4 light_color = light->getLightColor();
+ //send linear light color to shader
+ LLColor4 light_color = light->getLightLinearColor();
light_color.mV[3] = 0.0f;
F32 fade = iter->fade;
@@ -6347,13 +6382,24 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_color *= fade;
}
+ if (light_color.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
LLVector3 light_pos(light->getRenderPosition());
LLVector4 light_pos_gl(light_pos, 1.0f);
F32 light_radius = llmax(light->getLightRadius(), 0.001f);
+ F32 size = light_radius * (sRenderDeferred ? 1.5f : 1.0f);
- F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior.
- float linatten = x / (light_radius); // % of brightness at radius
+ if (size <= 0.001f)
+ {
+ continue;
+ }
+
+ F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior.
+ F32 linatten = x / (light_radius); // % of brightness at radius
mHWLightColors[cur_light] = light_color;
LLLightState* light_state = gGL.getLight(cur_light);
@@ -6364,9 +6410,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setConstantAttenuation(0.f);
if (sRenderDeferred)
{
- F32 size = light_radius*1.5f;
light_state->setLinearAttenuation(size);
- light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
+ light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights
}
else
{
@@ -6386,7 +6431,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setSpotCutoff(90.f);
light_state->setSpotExponent(2.f);
- const LLColor4 specular(0.f, 0.f, 0.f, 0.f);
+ LLVector3 spotParams = light->getSpotLightParams();
+
+ const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]);
light_state->setSpecular(specular);
}
else // omnidirectional (point) light
@@ -6394,8 +6441,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setSpotExponent(0.f);
light_state->setSpotCutoff(180.f);
- // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
- const LLColor4 specular(0.f, 0.f, 0.f, 1.f);
+ // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
+ const LLColor4 specular(0.f, 0.f, 1.f, 0.f);
light_state->setSpecular(specular);
}
cur_light++;
@@ -6409,45 +6456,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
{
mHWLightColors[cur_light] = LLColor4::black;
LLLightState* light = gGL.getLight(cur_light);
-
+ light->setSunPrimary(true);
light->setDiffuse(LLColor4::black);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
}
- if (gAgentAvatarp &&
- gAgentAvatarp->mSpecialRenderMode == 3)
- {
- LLColor4 light_color = LLColor4::white;
- light_color.mV[3] = 0.0f;
-
- LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin());
- LLVector4 light_pos_gl(light_pos, 1.0f);
- F32 light_radius = 16.f;
-
- F32 x = 3.f;
- float linatten = x / (light_radius); // % of brightness at radius
-
- if (LLPipeline::sRenderDeferred)
- {
- /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
- light_color.mV[1] = powf(light_color.mV[1], 2.2f);
- light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
- }
-
- mHWLightColors[2] = light_color;
- LLLightState* light = gGL.getLight(2);
-
- light->setPosition(light_pos_gl);
- light->setDiffuse(light_color);
- light->setAmbient(LLColor4::black);
- light->setSpecular(LLColor4::black);
- light->setQuadraticAttenuation(0.f);
- light->setConstantAttenuation(0.f);
- light->setLinearAttenuation(linatten);
- light->setSpotExponent(0.f);
- light->setSpotCutoff(180.f);
- }
+ // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode),
+ // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20
// Init GL state
if (!LLGLSLShader::sNoFixedFunction)
@@ -6508,9 +6524,6 @@ void LLPipeline::enableLights(U32 mask)
}
mLightMask = mask;
stop_glerror();
-
- LLColor4 ambient = gSky.getTotalAmbientColor();
- gGL.setAmbientLightColor(ambient);
}
}
@@ -6541,7 +6554,7 @@ void LLPipeline::enableLightsDynamic()
{
gPipeline.enableLightsAvatar();
}
- else if (gAgentAvatarp->mSpecialRenderMode >= 1) // anim preview
+ else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview
{
gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
}
@@ -6589,7 +6602,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse0);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular0);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
@@ -6600,7 +6613,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse1);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular1);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
@@ -6610,7 +6623,7 @@ void LLPipeline::enableLightsPreview()
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse2);
- light->setAmbient(LLColor4::black);
+ light->setAmbient(ambient);
light->setSpecular(specular2);
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
@@ -6626,13 +6639,11 @@ void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
gGL.setAmbientLightColor(color);
}
-void LLPipeline::enableLightsFullbright(const LLColor4& color)
+void LLPipeline::enableLightsFullbright()
{
assertInitialized();
U32 mask = 0x1000; // Non-0 mask, set ambient
enableLights(mask);
-
- gGL.setAmbientLightColor(color);
}
void LLPipeline::disableLights()
@@ -7142,7 +7153,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
{
if ((j == LLViewerRegion::PARTITION_VOLUME) ||
- (j == LLViewerRegion::PARTITION_BRIDGE) ||
+ (j == LLViewerRegion::PARTITION_BRIDGE) ||
+ (j == LLViewerRegion::PARTITION_CONTROL_AV) ||
(j == LLViewerRegion::PARTITION_TERRAIN) ||
(j == LLViewerRegion::PARTITION_TREE) ||
(j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now
@@ -7204,7 +7216,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
{
LLViewerRegion* region = *iter;
- LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
+ 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);
@@ -7458,6 +7470,15 @@ void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batc
gGLLastMatrix = NULL;
}
+void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
void apply_cube_face_rotation(U32 face)
{
@@ -7521,718 +7542,697 @@ void LLPipeline::bindScreenToTexture()
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
-void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
+void LLPipeline::renderFinalize()
{
- if (!(gPipeline.canUseVertexShaders() &&
- sRenderGlow))
- {
- return;
- }
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
+ LLGLState::checkTextureChannels();
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ assertInitialized();
- assertInitialized();
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
- if (gUseWireframe)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
- LLVector2 tc1(0,0);
- LLVector2 tc2((F32) mScreen.getWidth()*2,
- (F32) mScreen.getHeight()*2);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ gGL.color4f(1, 1, 1, 1);
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable cull(GL_CULL_FACE);
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
- gGL.color4f(1,1,1,1);
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable cull(GL_CULL_FACE);
-
- enableLightsFullbright(LLColor4(1,1,1,1));
+ enableLightsFullbright();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
- LLGLDisable test(GL_ALPHA_TEST);
+ LLGLDisable test(GL_ALPHA_TEST);
- gGL.setColorMask(true, true);
- glClearColor(0,0,0,0);
-
- {
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
- mGlow[2].bindTarget();
- mGlow[2].clear();
- }
-
- gGlowExtractProgram.bind();
- F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
- F32 maxAlpha = RenderGlowMaxExtractAlpha;
- F32 warmthAmount = RenderGlowWarmthAmount;
- LLVector3 lumWeights = RenderGlowLumWeights;
- LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
-
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
- LLGLEnable blend_on(GL_BLEND);
- LLGLEnable test(GL_ALPHA_TEST);
-
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-
- mScreen.bindTexture(0, 0);
-
- gGL.color4f(1,1,1,1);
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- 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(0)->unbind(mScreen.getUsage());
+ gGL.setColorMask(true, true);
+ glClearColor(0, 0, 0, 0);
- mGlow[2].flush();
- }
+ if (sRenderGlow)
+ {
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
+ }
- tc1.setVec(0,0);
- tc2.setVec(2,2);
+ gGlowExtractProgram.bind();
+ F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
+ F32 maxAlpha = RenderGlowMaxExtractAlpha;
+ F32 warmthAmount = RenderGlowWarmthAmount;
+ LLVector3 lumWeights = RenderGlowLumWeights;
+ LLVector3 warmthWeights = RenderGlowWarmthWeights;
+
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+ lumWeights.mV[2]);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+ warmthWeights.mV[2]);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+
+ {
+ LLGLEnable blend_on(GL_BLEND);
+ LLGLEnable test(GL_ALPHA_TEST);
- // power of two between 1 and 1024
- U32 glowResPow = RenderGlowResolutionPow;
- const U32 glow_res = llmax(1,
- llmin(1024, 1 << glowResPow));
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- S32 kernel = RenderGlowIterations*2;
- F32 delta = RenderGlowWidth / glow_res;
- // Use half the glow width if we have the res set to less than 9 so that it looks
- // almost the same in either case.
- if (glowResPow < 9)
- {
- delta *= 0.5f;
- }
- F32 strength = RenderGlowStrength;
+ mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
- gGlowProgram.bind();
- gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+ gGL.color4f(1, 1, 1, 1);
+ gPipeline.enableLightsFullbright();
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- for (S32 i = 0; i < kernel; i++)
- {
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
- mGlow[i%2].bindTarget();
- mGlow[i%2].clear();
- }
-
- if (i == 0)
- {
- gGL.getTexUnit(0)->bind(&mGlow[2]);
- }
- else
- {
- gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]);
- }
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- if (i%2 == 0)
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
- }
- else
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
- }
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- 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();
-
- mGlow[i%2].flush();
- }
+ gGL.end();
- gGlowProgram.unbind();
+ gGL.getTexUnit(0)->unbind(mScreen.getUsage());
- /*if (LLRenderTarget::sUseFBO)
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }*/
+ mGlow[2].flush();
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ tc1.setVec(0, 0);
+ tc2.setVec(2, 2);
+ }
- tc2.setVec((F32) mScreen.getWidth(),
- (F32) mScreen.getHeight());
+ // power of two between 1 and 1024
+ U32 glowResPow = RenderGlowResolutionPow;
+ const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
- gGL.flush();
-
- LLVertexBuffer::unbind();
+ S32 kernel = RenderGlowIterations * 2;
+ F32 delta = RenderGlowWidth / glow_res;
+ // Use half the glow width if we have the res set to less than 9 so that it looks
+ // almost the same in either case.
+ if (glowResPow < 9)
+ {
+ delta *= 0.5f;
+ }
+ F32 strength = RenderGlowStrength;
- if (LLPipeline::sRenderDeferred)
- {
+ gGlowProgram.bind();
+ gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
- bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField;
+ for (S32 i = 0; i < kernel; i++)
+ {
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
+ }
+ if (i == 0)
+ {
+ gGL.getTexUnit(0)->bind(&mGlow[2]);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
+ }
- bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+ if (i % 2 == 0)
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+ }
+ else
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+ }
- gViewerWindow->setup3DViewport();
-
- if (dof_enabled)
- {
- LLGLSLShader* shader = &gDeferredPostProgram;
- LLGLDisable blend(GL_BLEND);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- //depth of field focal plane calculations
- static F32 current_distance = 16.f;
- static F32 start_distance = 16.f;
- static F32 transition_time = 1.f;
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- LLVector3 focus_point;
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
- if (obj && obj->mDrawable && obj->isSelected())
- { //focus on selected media object
- S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
- if (obj && obj->mDrawable)
- {
- LLFace* face = obj->mDrawable->getFace(face_idx);
- if (face)
- {
- focus_point = face->getPositionAgent();
- }
- }
- }
-
- if (focus_point.isExactlyZero())
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- { //focus on point under cursor
- focus_point.set(gDebugRaycastIntersection.getF32ptr());
- }
- else if (gAgentCamera.cameraMouselook())
- { //focus on point under mouselook crosshairs
- LLVector4a result;
- result.clear();
+ gGL.end();
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
- NULL,
- &result);
+ mGlow[i % 2].flush();
+ }
- focus_point.set(result.getF32ptr());
- }
- else
- {
- //focus on alt-zoom target
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
- }
- }
- }
+ gGlowProgram.unbind();
+ }
+ else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ {
+ mGlow[1].bindTarget();
+ mGlow[1].clear();
+ mGlow[1].flush();
+ }
- LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
- F32 target_distance = 16.f;
- if (!focus_point.isExactlyZero())
- {
- target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye);
- }
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- if (transition_time >= 1.f &&
- fabsf(current_distance-target_distance)/current_distance > 0.01f)
- { //large shift happened, interpolate smoothly to new target distance
- transition_time = 0.f;
- start_distance = current_distance;
- }
- else if (transition_time < 1.f)
- { //currently in a transition, continue interpolating
- transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();
- transition_time = llmin(transition_time, 1.f);
+ tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
- F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
- current_distance = start_distance + (target_distance-start_distance)*t;
- }
- else
- { //small or no change, just snap to target distance
- current_distance = target_distance;
- }
+ gGL.flush();
- //convert to mm
- F32 subject_distance = current_distance*1000.f;
- F32 fnumber = CameraFNumber;
- F32 default_focal_length = CameraFocalLength;
+ LLVertexBuffer::unbind();
- F32 fov = LLViewerCamera::getInstance()->getView();
-
- const F32 default_fov = CameraFieldOfView * F_PI/180.f;
-
- //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
-
- F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+ if (LLPipeline::sRenderDeferred)
+ {
- F32 focal_length = dv/(2*tanf(fov/2.f));
-
- //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
-
- // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
- // where N = fnumber
- // s2 = dot distance
- // s1 = subject distance
- // f = focal length
- //
+ bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField;
- F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
- blur_constant /= 1000.f; //convert to meters for shader
- F32 magnification = focal_length/(subject_distance-focal_length);
+ bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
- { //build diffuse+bloom+CoF
- mDeferredLight.bindTarget();
- shader = &gDeferredCoFProgram;
+ gViewerWindow->setup3DViewport();
- bindDeferredShader(*shader);
+ if (dof_enabled)
+ {
+ LLGLSLShader *shader = &gDeferredPostProgram;
+ LLGLDisable blend(GL_BLEND);
+
+ // depth of field focal plane calculations
+ static F32 current_distance = 16.f;
+ static F32 start_distance = 16.f;
+ static F32 transition_time = 1.f;
+
+ LLVector3 focus_point;
+
+ LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+ if (obj && obj->mDrawable && obj->isSelected())
+ { // focus on selected media object
+ S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+ if (obj && obj->mDrawable)
+ {
+ LLFace *face = obj->mDrawable->getFace(face_idx);
+ if (face)
+ {
+ focus_point = face->getPositionAgent();
+ }
+ }
+ }
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- }
+ if (focus_point.isExactlyZero())
+ {
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ { // focus on point under cursor
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
+ }
+ else if (gAgentCamera.cameraMouselook())
+ { // focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
+
+ focus_point.set(result.getF32ptr());
+ }
+ else
+ {
+ // focus on alt-zoom target
+ LLViewerRegion *region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+ }
+ }
+ }
- shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f);
- shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
- shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle));
- shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ F32 target_distance = 16.f;
+ if (!focus_point.isExactlyZero())
+ {
+ target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ }
- 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();
+ if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+ { // large shift happened, interpolate smoothly to new target distance
+ transition_time = 0.f;
+ start_distance = current_distance;
+ }
+ else if (transition_time < 1.f)
+ { // currently in a transition, continue interpolating
+ transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+ transition_time = llmin(transition_time, 1.f);
- unbindDeferredShader(*shader);
- mDeferredLight.flush();
- }
+ F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+ current_distance = start_distance + (target_distance - start_distance) * t;
+ }
+ else
+ { // small or no change, just snap to target distance
+ current_distance = target_distance;
+ }
- U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale);
- U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale);
-
- { //perform DoF sampling at half-res (preserve alpha channel)
- mScreen.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());
- if (channel > -1)
- {
- mDeferredLight.bindTexture(0, channel);
- }
+ // convert to mm
+ F32 subject_distance = current_distance * 1000.f;
+ F32 fnumber = CameraFNumber;
+ F32 default_focal_length = CameraFocalLength;
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
-
- 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();
+ F32 fov = LLViewerCamera::getInstance()->getView();
- unbindDeferredShader(*shader);
- mScreen.flush();
- gGL.setColorMask(true, true);
- }
-
- { //combine result based on alpha
- if (multisample)
- {
- mDeferredLight.bindTarget();
- glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
- }
- else
- {
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- }
+ const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
- shader = &gDeferredDoFCombineProgram;
- bindDeferredShader(*shader);
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- }
+ // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
- if (!LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
- } else {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
- }
+ F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1);
- shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1);
+ F32 focal_length = dv / (2 * tanf(fov / 2.f));
- 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();
+ // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
- unbindDeferredShader(*shader);
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
- if (multisample)
- {
- mDeferredLight.flush();
- }
- }
- }
- else
- {
- if (multisample)
- {
- mDeferredLight.bindTarget();
- }
- LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
-
- bindDeferredShader(*shader);
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- }
+ F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+ blur_constant /= 1000.f; // convert to meters for shader
+ F32 magnification = focal_length / (subject_distance - focal_length);
- if (!LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
- } else {
- shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
- }
+ { // build diffuse+bloom+CoF
+ mDeferredLight.bindTarget();
+ shader = &gDeferredCoFProgram;
- 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();
+ bindDeferredShader(*shader);
- unbindDeferredShader(*shader);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0, channel);
+ }
- if (multisample)
- {
- mDeferredLight.flush();
- }
- }
+ shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+ shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+ shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+ shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+ shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- if (multisample)
- {
- //bake out texture2D with RGBL for FXAA shader
- mFXAABuffer.bindTarget();
-
- S32 width = mScreen.getWidth();
- S32 height = mScreen.getHeight();
- glViewport(0, 0, width, height);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- LLGLSLShader* shader = &gGlowCombineFXAAProgram;
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- shader->bind();
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
- if (channel > -1)
- {
- mDeferredLight.bindTexture(0, channel);
- }
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1,-1);
- gGL.vertex2f(-1,3);
- gGL.vertex2f(3,-1);
- gGL.end();
+ gGL.end();
- gGL.flush();
+ unbindDeferredShader(*shader);
+ mDeferredLight.flush();
+ }
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
- shader->unbind();
-
- mFXAABuffer.flush();
+ U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
- shader = &gFXAAProgram;
- shader->bind();
+ { // perform DoF sampling at half-res (preserve alpha channel)
+ mScreen.bindTarget();
+ glViewport(0, 0, dof_width, dof_height);
+ gGL.setColorMask(true, false);
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
- if (channel > -1)
- {
- mFXAABuffer.bindTexture(0, channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- }
-
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- 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();
- 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, 0.5f/width*scale_x, 0.5f/height*scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y);
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1,-1);
- gGL.vertex2f(-1,3);
- gGL.vertex2f(3,-1);
- gGL.end();
+ shader = &gDeferredPostProgram;
+ bindDeferredShader(*shader);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ if (channel > -1)
+ {
+ mDeferredLight.bindTexture(0, channel);
+ }
- gGL.flush();
- shader->unbind();
- }
- }
- else
- {
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
- buff->allocateBuffer(3,0,TRUE);
+ shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- LLStrider<LLVector3> v;
- LLStrider<LLVector2> uv1;
- LLStrider<LLVector2> uv2;
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- buff->getVertexStrider(v);
- buff->getTexCoord0Strider(uv1);
- buff->getTexCoord1Strider(uv2);
-
- uv1[0] = LLVector2(0, 0);
- uv1[1] = LLVector2(0, 2);
- uv1[2] = LLVector2(2, 0);
-
- uv2[0] = LLVector2(0, 0);
- uv2[1] = LLVector2(0, tc2.mV[1]*2.f);
- uv2[2] = LLVector2(tc2.mV[0]*2.f, 0);
-
- v[0] = LLVector3(-1,-1,0);
- v[1] = LLVector3(-1,3,0);
- v[2] = LLVector3(3,-1,0);
-
- buff->flush();
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- LLGLDisable blend(GL_BLEND);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gGlowCombineProgram.bind();
- }
- else
- {
- //tex unit 0
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
- //tex unit 1
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
- }
-
- gGL.getTexUnit(0)->bind(&mGlow[1]);
- gGL.getTexUnit(1)->bind(&mScreen);
-
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
- buff->setBuffer(mask);
- buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- gGlowCombineProgram.unbind();
- }
- else
- {
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+ gGL.end();
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
-
- }
+ unbindDeferredShader(*shader);
+ mScreen.flush();
+ gGL.setColorMask(true, true);
+ }
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ { // combine result based on alpha
+ if (multisample)
+ {
+ mDeferredLight.bindTarget();
+ glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ }
+ else
+ {
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ }
+
+ shader = &gDeferredDoFCombineProgram;
+ bindDeferredShader(*shader);
+
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0, channel);
+ }
+
+ shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1);
+ shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1);
+
+ 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();
+
+ unbindDeferredShader(*shader);
+
+ if (multisample)
+ {
+ mDeferredLight.flush();
+ }
+ }
+ }
+ else
+ {
+ if (multisample)
+ {
+ mDeferredLight.bindTarget();
+ }
+ LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
- {
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSplatTextureRectProgram.bind();
- }
+ bindDeferredShader(*shader);
- gGL.setColorMask(true, false);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0, channel);
+ }
- LLVector2 tc1(0,0);
- LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
- (F32) gViewerWindow->getWorldViewHeightRaw()*2);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- LLGLEnable blend(GL_BLEND);
- gGL.color4f(1,1,1,0.75f);
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- gGL.begin(LLRender::TRIANGLES);
- 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.flush();
+ gGL.end();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSplatTextureRectProgram.unbind();
- }
- }
+ unbindDeferredShader(*shader);
-
- 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(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
-
+ if (multisample)
+ {
+ mDeferredLight.flush();
+ }
+ }
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ if (multisample)
+ {
+ // bake out texture2D with RGBL for FXAA shader
+ mFXAABuffer.bindTarget();
- LLVertexBuffer::unbind();
+ S32 width = mScreen.getWidth();
+ S32 height = mScreen.getHeight();
+ glViewport(0, 0, width, height);
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ LLGLSLShader *shader = &gGlowCombineFXAAProgram;
+
+ shader->bind();
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ if (channel > -1)
+ {
+ mDeferredLight.bindTexture(0, channel);
+ }
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 3);
+ gGL.vertex2f(3, -1);
+ gGL.end();
+
+ gGL.flush();
+
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ shader->unbind();
+
+ mFXAABuffer.flush();
+
+ shader = &gFXAAProgram;
+ shader->bind();
+
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
+ if (channel > -1)
+ {
+ mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ 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();
+ 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,
+ 0.5f / width * scale_x, 0.5f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+ 2.f / width * scale_x, 2.f / height * scale_y);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 3);
+ gGL.vertex2f(3, -1);
+ gGL.end();
+
+ gGL.flush();
+ shader->unbind();
+ }
+ }
+ else // not deferred
+ {
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
+ buff->allocateBuffer(3, 0, TRUE);
+
+ LLStrider<LLVector3> v;
+ LLStrider<LLVector2> uv1;
+ LLStrider<LLVector2> uv2;
+
+ buff->getVertexStrider(v);
+ buff->getTexCoord0Strider(uv1);
+ buff->getTexCoord1Strider(uv2);
+
+ uv1[0] = LLVector2(0, 0);
+ uv1[1] = LLVector2(0, 2);
+ uv1[2] = LLVector2(2, 0);
+
+ uv2[0] = LLVector2(0, 0);
+ uv2[1] = LLVector2(0, tc2.mV[1] * 2.f);
+ uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0);
+
+ v[0] = LLVector3(-1, -1, 0);
+ v[1] = LLVector3(-1, 3, 0);
+ v[2] = LLVector3(3, -1, 0);
+
+ buff->flush();
+
+ LLGLDisable blend(GL_BLEND);
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gGlowCombineProgram.bind();
+ }
+ else
+ {
+ // tex unit 0
+ gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
+ // tex unit 1
+ gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR,
+ LLTexUnit::TBS_PREV_COLOR);
+ }
+
+ gGL.getTexUnit(0)->bind(&mGlow[1]);
+ gGL.getTexUnit(1)->bind(&mScreen);
+
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+ buff->setBuffer(mask);
+ buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gGlowCombineProgram.unbind();
+ }
+ else
+ {
+ gGL.getTexUnit(1)->disable();
+ gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+ }
+ }
+
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gSplatTextureRectProgram.bind();
+ }
+
+ gGL.setColorMask(true, false);
+
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2,
+ (F32) gViewerWindow->getWorldViewHeightRaw() * 2);
+
+ LLGLEnable blend(GL_BLEND);
+ gGL.color4f(1, 1, 1, 0.75f);
+
+ gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+
+ gGL.begin(LLRender::TRIANGLES);
+ 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.flush();
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ 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(),
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ LLVertexBuffer::unbind();
+
+ LLGLState::checkStates();
+ LLGLState::checkTextureChannels();
}
static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED);
- if (noise_map == 0xFFFFFFFF)
- {
- noise_map = mNoiseMap;
- }
+ LLRenderTarget* deferred_target = &mDeferredScreen;
+ LLRenderTarget* deferred_depth_target = &mDeferredDepth;
+ LLRenderTarget* deferred_light_target = &mDeferredLight;
shader.bind();
S32 channel = 0;
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(0,channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(1, channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(2, channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
if (channel > -1)
{
- gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
+ gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
stop_glerror();
+ }
- //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
- //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
-
- stop_glerror();
-
- glh::matrix4f projection = glh_get_current_projection();
+ glh::matrix4f projection = get_current_projection();
glh::matrix4f inv_proj = projection.inverse();
+ if (shader.getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX) != -1)
+ {
shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ }
+
+ if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
+ {
shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
(F32) gGLViewport[1],
(F32) gGLViewport[2],
(F32) gGLViewport[3]);
}
+ if (sReflectionRender && !shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX))
+ {
+ shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m);
+ }
+
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);
if (channel > -1)
{
- gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map);
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -8244,18 +8244,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
stop_glerror();
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
+ light_target = light_target ? light_target : deferred_light_target;
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage());
if (channel > -1)
{
- if (light_index > 0)
- {
- mScreen.bindTexture(0, channel);
- }
- else
- {
- mDeferredLight.bindTexture(0, channel);
- }
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -8268,13 +8261,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
for (U32 i = 0; i < 4; i++)
{
+ LLRenderTarget* shadow_target = getShadowTarget(i);
+ if (shadow_target)
+ {
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
stop_glerror();
if (channel > -1)
{
stop_glerror();
- gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
@@ -8283,6 +8279,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
stop_glerror();
}
}
+ }
for (U32 i = 4; i < 6; i++)
{
@@ -8291,8 +8288,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
if (channel > -1)
{
stop_glerror();
- gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ 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();
@@ -8301,6 +8301,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
stop_glerror();
}
}
+ }
stop_glerror();
@@ -8337,6 +8338,34 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+ if (gAtmosphere)
+ {
+ // bind precomputed textures necessary for calculating sun and sky luminance
+ channel = shader.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance());
+ }
+ }
+
shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
@@ -8361,26 +8390,35 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
//F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f;
+ F32 shadow_bias = RenderShadowBias + shadow_bias_error;
- shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias+shadow_bias_error);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, shadow_bias);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias);
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.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
-
if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
- glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
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);
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t sky = environment.getCurrentSky();
+
+ static_cast<LLSettingsVOSky*>(sky.get())->updateShader(&shader);
}
LLColor3 pow3f(LLColor3 v, F32 f)
@@ -8410,1150 +8448,622 @@ static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");
static LLTrace::BlockTimerStatHandle FTM_POST("Post");
-
-void LLPipeline::renderDeferredLighting()
-{
- if (!sCull)
- {
- return;
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
-
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- {
- LLGLDepthTest depth(GL_TRUE);
- mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- }
-
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
- if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- }
-
- //ati doesn't seem to love actually using the stencil buffer on FBO's
- LLGLDisable stencil(GL_STENCIL_TEST);
- //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
- //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
- gGL.setColorMask(true, true);
-
- //draw a cube around every light
- LLVertexBuffer::unbind();
-
- LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable blend(GL_BLEND);
-
- glh::matrix4f mat = glh_copy_matrix(gGLModelView);
-
- LLStrider<LLVector3> vert;
- mDeferredVB->getVertexStrider(vert);
-
- vert[0].set(-1,1,0);
- vert[1].set(-1,-3,0);
- vert[2].set(3,1,0);
-
- {
- setupHWLights(NULL); //to set mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
- mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
- }
-
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- if (RenderDeferredSSAO || RenderShadowDetail > 0)
- {
- mDeferredLight.bindTarget();
- { //paint shadow/SSAO light map (direct lighting lightmap)
- LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
- bindDeferredShader(gDeferredSunProgram, 0);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glClearColor(1,1,1,1);
- mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
-
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
-
- const U32 slice = 32;
- F32 offset[slice*3];
- for (U32 i = 0; i < 4; i++)
- {
- for (U32 j = 0; j < 8; j++)
- {
- glh::vec3f v;
- v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
- v.normalize();
- inv_trans.mult_matrix_vec(v);
- v.normalize();
- offset[(i*8+j)*3+0] = v.v[0];
- offset[(i*8+j)*3+1] = v.v[2];
- offset[(i*8+j)*3+2] = v.v[1];
- }
- }
-
- gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
- gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
-
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
-
- unbindDeferredShader(gDeferredSunProgram);
- }
- mDeferredLight.flush();
- }
-
- if (RenderDeferredSSAO)
- { //soften direct lighting lightmap
- LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
- //blur lightmap
- mScreen.bindTarget();
- glClearColor(1,1,1,1);
- mScreen.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;
-
- // sample symmetrically with the middle sample falling exactly on 0.0
- F32 x = 0.f;
-
- 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;
- }
-
- 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();
- }
-
- mScreen.flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
-
- bindDeferredShader(gDeferredBlurLightProgram, 1);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredLight.bindTarget();
-
- 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();
- }
- mDeferredLight.flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
- }
-
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
-
- mScreen.bindTarget();
- // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
- glClearColor(0,0,0,0);
- mScreen.clear(GL_COLOR_BUFFER_BIT);
-
- if (RenderDeferredAtmospheric)
- { //apply sunlight contribution
- LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
- bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
- {
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
-
- //full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
-
- unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
- }
-
- { //render non-deferred geometry (fullbright, alpha, etc)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- gPipeline.pushRenderTypeMask();
-
- gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
-
-
- renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
- gPipeline.popRenderTypeMask();
- }
-
- bool render_local = RenderLocalLights;
-
- if (render_local)
- {
- gGL.setSceneBlendType(LLRender::BT_ADD);
- std::list<LLVector4> fullscreen_lights;
- LLDrawable::drawable_list_t spot_lights;
- LLDrawable::drawable_list_t fullscreen_spot_lights;
-
- for (U32 i = 0; i < 2; i++)
- {
- mTargetShadowSpotLight[i] = NULL;
- }
-
- std::list<LLVector4> light_colors;
-
- LLVertexBuffer::unbind();
-
- {
- bindDeferredShader(gDeferredLightProgram);
-
- if (mCubeVB.isNull())
- {
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
- }
-
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
- if (!volume)
- {
- continue;
- }
-
- if (volume->isAttachment())
- {
- if (!sRenderAttachedLights)
- {
- continue;
- }
- }
-
- const LLViewerObject *vobj = drawablep->getVObj();
- if(vobj && vobj->getAvatar()
- && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()))
- {
- continue;
- }
-
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
-
- LLColor3 col = volume->getLightColor();
-
- if (col.magVecSquared() < 0.001f)
- {
- continue;
- }
-
- if (s <= 0.001f)
- {
- continue;
- }
-
- LLVector4a sa;
- sa.splat(s);
- if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
- {
- continue;
- }
-
- sVisibleLightCount++;
-
- if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
- camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
- camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
- camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
- camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
- camera->getOrigin().mV[2] < c[2] - s - 0.2f)
- { //draw box if camera is outside box
- if (render_local)
- {
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- spot_lights.push_back(drawablep);
- continue;
- }
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- stop_glerror();
- }
- }
- else
- {
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- fullscreen_spot_lights.push_back(drawablep);
- continue;
- }
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
- light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
- }
- }
- unbindDeferredShader(gDeferredLightProgram);
- }
-
- if (!spot_lights.empty())
- {
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- bindDeferredShader(gDeferredSpotLightProgram);
-
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-
- for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
-
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
-
- sVisibleLightCount++;
-
- setupSpotLight(gDeferredSpotLightProgram, drawablep);
-
- LLColor3 col = volume->getLightColor();
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- }
- gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- unbindDeferredShader(gDeferredSpotLightProgram);
- }
-
- //reset mDeferredVB to fullscreen triangle
- mDeferredVB->getVertexStrider(vert);
- vert[0].set(-1,1,0);
- vert[1].set(-1,-3,0);
- vert[2].set(3,1,0);
-
- {
- LLGLDepthTest depth(GL_FALSE);
-
- //full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- U32 count = 0;
-
- const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
- LLVector4 light[max_count];
- LLVector4 col[max_count];
-
- F32 far_z = 0.f;
-
- while (!fullscreen_lights.empty())
- {
- LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
- light[count] = fullscreen_lights.front();
- fullscreen_lights.pop_front();
- col[count] = light_colors.front();
- light_colors.pop_front();
-
- /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
- col[count].mV[1] = powf(col[count].mV[1], 2.2f);
- col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
-
- far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
- //col[count] = pow4fsrgb(col[count], 2.2f);
- count++;
- if (count == max_count || fullscreen_lights.empty())
- {
- U32 idx = count-1;
- bindDeferredShader(gDeferredMultiLightProgram[idx]);
- gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
- far_z = 0.f;
- count = 0;
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- unbindDeferredShader(gDeferredMultiLightProgram[idx]);
- }
- }
-
- bindDeferredShader(gDeferredMultiSpotLightProgram);
-
- gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
-
- LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
- F32 s = volume->getLightRadius()*1.5f;
-
- sVisibleLightCount++;
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
-
- LLColor3 col = volume->getLightColor();
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- unbindDeferredShader(gDeferredMultiSpotLightProgram);
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
- }
-
- gGL.setColorMask(true, true);
- }
-
- mScreen.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) mScreen.getWidth()*2,
- (F32) mScreen.getHeight()*2);
-
- mScreen.bindTarget();
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
- //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- S32 channel = 0;
- channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0,channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.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(mScreen.getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- mScreen.flush();
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- mScreen.bindTarget();
-
- { //render non-deferred geometry (alpha, fullbright, glow)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
-
- pushRenderTypeMask();
- andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_GLOW,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
- LLPipeline::RENDER_TYPE_PASS_GLOW,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SHINY,
- LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
- LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
- 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();
- }
- }
-
- mScreen.flush();
-
-}
-
-void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
+void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
- if (!sCull)
- {
- return;
- }
+ if (!sCull)
+ {
+ return;
+ }
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
-
- LLViewerCamera* camera = LLViewerCamera::getInstance();
+ LLRenderTarget *deferred_target = &mDeferredScreen;
+ LLRenderTarget *deferred_depth_target = &mDeferredDepth;
+ LLRenderTarget *deferred_light_target = &mDeferredLight;
- {
- LLGLDepthTest depth(GL_TRUE);
- mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
-
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
- if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
- }
-
- //ati doesn't seem to love actually using the stencil buffer on FBO's
- LLGLDisable stencil(GL_STENCIL_TEST);
- //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
- //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
+ LLViewerCamera *camera = LLViewerCamera::getInstance();
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ deferred_depth_target->copyContents(*deferred_target,
+ 0,
+ 0,
+ deferred_target->getWidth(),
+ deferred_target->getHeight(),
+ 0,
+ 0,
+ deferred_depth_target->getWidth(),
+ deferred_depth_target->getHeight(),
+ GL_DEPTH_BUFFER_BIT,
+ GL_NEAREST);
+ }
- gGL.setColorMask(true, true);
-
- //draw a cube around every light
- LLVertexBuffer::unbind();
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
- LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable blend(GL_BLEND);
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
- glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+ // ati doesn't seem to love actually using the stencil buffer on FBO's
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+ // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- LLStrider<LLVector3> vert;
- mDeferredVB->getVertexStrider(vert);
-
- vert[0].set(-1,1,0);
- vert[1].set(-1,-3,0);
- vert[2].set(3,1,0);
-
- {
- setupHWLights(NULL); //to set mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
- mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
- }
+ gGL.setColorMask(true, true);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ // draw a cube around every light
+ LLVertexBuffer::unbind();
- if (RenderDeferredSSAO || RenderShadowDetail > 0)
- {
- mDeferredLight.bindTarget();
- { //paint shadow/SSAO light map (direct lighting lightmap)
- LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
- bindDeferredShader(gDeferredSunProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glClearColor(1,1,1,1);
- mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f mat = copy_matrix(gGLModelView);
- const U32 slice = 32;
- F32 offset[slice*3];
- for (U32 i = 0; i < 4; i++)
- {
- for (U32 j = 0; j < 8; j++)
- {
- glh::vec3f v;
- v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
- v.normalize();
- inv_trans.mult_matrix_vec(v);
- v.normalize();
- offset[(i*8+j)*3+0] = v.v[0];
- offset[(i*8+j)*3+1] = v.v[2];
- offset[(i*8+j)*3+2] = v.v[1];
- }
- }
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
- gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
- gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
-
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
-
- unbindDeferredShader(gDeferredSunProgram);
- }
- mDeferredLight.flush();
- }
-
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
+ vert[0].set(-1, 1, 0);
+ vert[1].set(-1, -3, 0);
+ vert[2].set(3, 1, 0);
- target->bindTarget();
+ setupHWLights(NULL); // to set mSun/MoonDir;
- //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
- glClearColor(0,0,0,0);
- target->clear(GL_COLOR_BUFFER_BIT);
-
- if (RenderDeferredAtmospheric)
- { //apply sunlight contribution
- LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
- {
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
+ glh::vec4f tc(mSunDir.mV);
+ mat.mult_matrix_vec(tc);
+ mTransformedSunDir.set(tc.v);
- //full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ glh::vec4f tc_moon(mMoonDir.mV);
+ mat.mult_matrix_vec(tc_moon);
+ mTransformedMoonDir.set(tc_moon.v);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
+ if (RenderDeferredSSAO || RenderShadowDetail > 0)
+ {
+ deferred_light_target->bindTarget();
+ { // paint shadow/SSAO light map (direct lighting lightmap)
+ LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
+ bindDeferredShader(gDeferredSunProgram, deferred_light_target);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glClearColor(1, 1, 1, 1);
+ deferred_light_target->clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0, 0, 0, 0);
+
+ glh::matrix4f inv_trans = get_current_modelview().inverse().transpose();
+
+ const U32 slice = 32;
+ F32 offset[slice * 3];
+ for (U32 i = 0; i < 4; i++)
+ {
+ for (U32 j = 0; j < 8; j++)
+ {
+ glh::vec3f v;
+ v.set_value(sinf(6.284f / 8 * j), cosf(6.284f / 8 * j), -(F32) i);
+ v.normalize();
+ inv_trans.mult_matrix_vec(v);
+ v.normalize();
+ offset[(i * 8 + j) * 3 + 0] = v.v[0];
+ offset[(i * 8 + j) * 3 + 1] = v.v[2];
+ offset[(i * 8 + j) * 3 + 2] = v.v[1];
+ }
+ }
+
+ gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES,
+ deferred_light_target->getWidth(),
+ deferred_light_target->getHeight());
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+
+ unbindDeferredShader(gDeferredSunProgram);
+ }
+ deferred_light_target->flush();
+ }
- unbindDeferredShader(gDeferredSoftenProgram);
- }
+ if (RenderDeferredSSAO)
+ { // soften direct lighting lightmap
+ LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
+ // blur lightmap
+ screen_target->bindTarget();
+ glClearColor(1, 1, 1, 1);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0, 0, 0, 0);
- { //render non-deferred geometry (fullbright, alpha, etc)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ bindDeferredShader(gDeferredBlurLightProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ LLVector3 go = RenderShadowGaussian;
+ const U32 kern_length = 4;
+ F32 blur_size = RenderShadowBlurSize;
+ F32 dist_factor = RenderShadowBlurDistFactor;
- gPipeline.pushRenderTypeMask();
-
- gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
-
-
- renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
- gPipeline.popRenderTypeMask();
- }
+ // sample symmetrically with the middle sample falling exactly on 0.0
+ F32 x = 0.f;
- bool render_local = RenderLocalLights;
-
- if (render_local)
- {
- gGL.setSceneBlendType(LLRender::BT_ADD);
- std::list<LLVector4> fullscreen_lights;
- LLDrawable::drawable_list_t spot_lights;
- LLDrawable::drawable_list_t fullscreen_spot_lights;
+ LLVector3 gauss[32]; // xweight, yweight, offset
- for (U32 i = 0; i < 2; i++)
- {
- mTargetShadowSpotLight[i] = NULL;
- }
+ 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;
+ }
- std::list<LLVector4> light_colors;
+ 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));
- LLVertexBuffer::unbind();
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
- {
- bindDeferredShader(gDeferredLightProgram);
-
- if (mCubeVB.isNull())
- {
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
- }
+ screen_target->flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
- if (!volume)
- {
- continue;
- }
+ bindDeferredShader(gDeferredBlurLightProgram, screen_target);
- if (volume->isAttachment())
- {
- if (!sRenderAttachedLights)
- {
- continue;
- }
- }
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ deferred_light_target->bindTarget();
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
+ {
+ 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);
+ }
- LLColor3 col = volume->getLightColor();
-
- if (col.magVecSquared() < 0.001f)
- {
- continue;
- }
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
- if (s <= 0.001f)
- {
- continue;
- }
+ screen_target->bindTarget();
+ // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0, 0, 0, 0);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
- LLVector4a sa;
- sa.splat(s);
- if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
- {
- continue;
- }
+ if (RenderDeferredAtmospheric)
+ { // apply sunlight contribution
+ LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
- sVisibleLightCount++;
-
- if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
- camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
- camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
- camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
- camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
- camera->getOrigin().mV[2] < c[2] - s - 0.2f)
- { //draw box if camera is outside box
- if (render_local)
- {
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- spot_lights.push_back(drawablep);
- continue;
- }
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- stop_glerror();
- }
- }
- else
- {
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- fullscreen_spot_lights.push_back(drawablep);
- continue;
- }
+ LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
+ bindDeferredShader(soften_shader);
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
- light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
- }
- }
- unbindDeferredShader(gDeferredLightProgram);
- }
+ LLEnvironment &environment = LLEnvironment::instance();
+ soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
- if (!spot_lights.empty())
- {
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- bindDeferredShader(gDeferredSpotLightProgram);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ // full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
- gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- LLVOVolume* volume = drawablep->getVOVolume();
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
+ unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
+ }
- sVisibleLightCount++;
+ { // render non-deferred geometry (fullbright, alpha, etc)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
- setupSpotLight(gDeferredSpotLightProgram, drawablep);
-
- LLColor3 col = volume->getLightColor();
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- }
- gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- unbindDeferredShader(gDeferredSpotLightProgram);
- }
+ gPipeline.pushRenderTypeMask();
- //reset mDeferredVB to fullscreen triangle
- mDeferredVB->getVertexStrider(vert);
- vert[0].set(-1,1,0);
- vert[1].set(-1,-3,0);
- vert[2].set(3,1,0);
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
- {
- LLGLDepthTest depth(GL_FALSE);
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+ gPipeline.popRenderTypeMask();
+ }
- //full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ bool render_local = RenderLocalLights;
- U32 count = 0;
+ if (render_local)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ std::list<LLVector4> fullscreen_lights;
+ LLDrawable::drawable_list_t spot_lights;
+ LLDrawable::drawable_list_t fullscreen_spot_lights;
- const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
- LLVector4 light[max_count];
- LLVector4 col[max_count];
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
- F32 far_z = 0.f;
+ std::list<LLVector4> light_colors;
- while (!fullscreen_lights.empty())
- {
- LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
- light[count] = fullscreen_lights.front();
- fullscreen_lights.pop_front();
- col[count] = light_colors.front();
- light_colors.pop_front();
-
- /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
- col[count].mV[1] = powf(col[count].mV[1], 2.2f);
- col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
-
- far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
- //col[count] = pow4fsrgb(col[count], 2.2f);
- count++;
- if (count == max_count || fullscreen_lights.empty())
- {
- U32 idx = count-1;
- bindDeferredShader(gDeferredMultiLightProgram[idx]);
- gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
- far_z = 0.f;
- count = 0;
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
- }
-
- unbindDeferredShader(gDeferredMultiLightProgram[0]);
+ LLVertexBuffer::unbind();
- bindDeferredShader(gDeferredMultiSpotLightProgram);
+ {
+ bindDeferredShader(gDeferredLightProgram);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ // mNearbyLights already includes distance calculation and excludes muted avatars.
+ // It is calculated from mLights
+ // mNearbyLights also provides fade value to gracefully fade-out out of range lights
+ for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter)
+ {
+ LLDrawable * drawablep = iter->drawable;
+ LLVOVolume * volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32 *c = center.getF32ptr();
+ F32 s = volume->getLightRadius() * 1.5f;
+
+ // send light color to shader in linear space
+ LLColor3 col = volume->getLightLinearColor();
+
+ if (col.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
+ if (s <= 0.001f)
+ {
+ continue;
+ }
+
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+ {
+ continue;
+ }
+
+ sVisibleLightCount++;
+
+ if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+ camera->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+ camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+ { // draw box if camera is outside box
+ if (render_local)
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ stop_glerror();
+ }
+ }
+ else
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ fullscreen_spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
+ light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)));
+ }
+ }
+
+ // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode),
+ // prev site of appended deferred character light, removed by SL-13522 09/20
+
+ unbindDeferredShader(gDeferredLightProgram);
+ }
- gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ if (!spot_lights.empty())
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ bindDeferredShader(gDeferredSpotLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
+ gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
- F32 s = volume->getLightRadius()*1.5f;
+ for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+ LLDrawable *drawablep = *iter;
- sVisibleLightCount++;
+ LLVOVolume *volume = drawablep->getVOVolume();
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32 *c = center.getF32ptr();
+ F32 s = volume->getLightRadius() * 1.5f;
- LLColor3 col = volume->getLightColor();
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
+ sVisibleLightCount++;
- gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- unbindDeferredShader(gDeferredMultiSpotLightProgram);
+ setupSpotLight(gDeferredSpotLightProgram, drawablep);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- }
- }
+ // send light color to shader in linear space
+ LLColor3 col = volume->getLightLinearColor();
- gGL.setColorMask(true, true);
- }
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+ gGL.syncMatrices();
- /*target->flush();
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ }
+ gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredSpotLightProgram);
+ }
- //gamma correct lighting
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ // reset mDeferredVB to fullscreen triangle
+ mDeferredVB->getVertexStrider(vert);
+ vert[0].set(-1, 1, 0);
+ vert[1].set(-1, -3, 0);
+ vert[2].set(3, 1, 0);
- {
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+
+ // full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ U32 count = 0;
+
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+ LLVector4 light[max_count];
+ LLVector4 col[max_count];
+
+ F32 far_z = 0.f;
+
+ while (!fullscreen_lights.empty())
+ {
+ LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
+ light[count] = fullscreen_lights.front();
+ fullscreen_lights.pop_front();
+ col[count] = light_colors.front();
+ light_colors.pop_front();
+
+ far_z = llmin(light[count].mV[2] - light[count].mV[3], far_z);
+ count++;
+ if (count == max_count || fullscreen_lights.empty())
+ {
+ U32 idx = count - 1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ far_z = 0.f;
+ count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
+ }
+ }
+
+ bindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+ LLDrawable *drawablep = *iter;
+ LLVOVolume *volume = drawablep->getVOVolume();
+ LLVector3 center = drawablep->getPositionAgent();
+ F32 * c = center.mV;
+ F32 light_size_final = volume->getLightRadius() * 1.5f;
+ F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
+
+ sVisibleLightCount++;
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+
+ // send light color to shader in linear space
+ LLColor3 col = volume->getLightLinearColor();
+
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final);
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+ }
- LLVector2 tc1(0,0);
- LLVector2 tc2((F32) target->getWidth()*2,
- (F32) target->getHeight()*2);
+ gGL.setColorMask(true, true);
+ }
- 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, target->getUsage());
- if (channel > -1)
- {
- target->bindTexture(0,channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight());
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ screen_target->flush();
- 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(target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- target->flush();
- }
+ // gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- target->bindTarget();*/
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);
- { //render non-deferred geometry (alpha, fullbright, glow)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ 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);
+ }
- pushRenderTypeMask();
- andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_GLOW,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
- LLPipeline::RENDER_TYPE_PASS_GLOW,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SHINY,
- LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
- LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
- END_RENDER_TYPES);
-
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
- popRenderTypeMask();
- }
+ 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);
+
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ 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();
+ }
+ }
- //target->flush();
+ screen_target->flush();
}
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
@@ -9585,7 +9095,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
- glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent;
+ glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent;
glh::matrix4f screen_to_light = light_to_screen.inverse();
@@ -9697,12 +9207,16 @@ 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;
+
stop_glerror();
- shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
+ 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_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -9747,327 +9261,300 @@ inline float sgn(float a)
}
void LLPipeline::generateWaterReflection(LLCamera& camera_in)
-{
- if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
- }
- LLVertexBuffer::unbind();
+{
+ if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
+ {
+ bool skip_avatar_update = false;
+ if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
+ {
+ skip_avatar_update = true;
+ }
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
+ LLCamera camera = camera_in;
+ camera.setFar(camera_in.getFar() * 0.75f);
- LLCamera camera = camera_in;
- camera.setFar(camera.getFar()*0.87654321f);
- LLPipeline::sReflectionRender = true;
-
- gPipeline.pushRenderTypeMask();
+ bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
- glh::matrix4f projection = glh_get_current_projection();
- glh::matrix4f mat;
+ LLPipeline::sReflectionRender = true;
- stop_glerror();
- LLPlane plane;
+ gPipeline.pushRenderTypeMask();
- F32 height = gAgent.getRegion()->getWaterHeight();
- F32 to_clip = fabsf(camera.getOrigin().mV[2]-height);
- F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by
+ glh::matrix4f saved_modelview = get_current_modelview();
+ glh::matrix4f saved_projection = get_current_projection();
+ glh::matrix4f mat;
- //plane params
- LLVector3 pnorm;
- F32 pd;
+ S32 reflection_detail = RenderReflectionDetail;
- S32 water_clip = 0;
- if (!LLViewerCamera::getInstance()->cameraUnderWater())
- { //camera is above water, clip plane points up
- pnorm.setVec(0,0,1);
- pd = -height;
- plane.setVec(pnorm, pd);
- water_clip = -1;
- }
- else
- { //camera is below water, clip plane points down
- pnorm = LLVector3(0,0,-1);
- pd = height;
- plane.setVec(pnorm, pd);
- water_clip = 1;
- }
+ 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);
- bool materials_in_water = false;
+ 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);
-#if MATERIALS_IN_REFLECTIONS
- materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
-#endif
+ camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
- if (!LLViewerCamera::getInstance()->cameraUnderWater())
- { //generate planar reflection map
+ //plane params
+ LLPlane plane;
+ LLVector3 pnorm;
+ S32 water_clip = 0;
+ if (!camera_is_underwater)
+ {
+ //camera is above water, clip plane points up
+ pnorm.setVec(0,0,1);
+ plane.setVec(pnorm, -water_height);
+ water_clip = 1;
+ }
+ else
+ {
+ //camera is below water, clip plane points down
+ pnorm = LLVector3(0,0,-1);
+ plane.setVec(pnorm, water_height);
+ water_clip = -1;
+ }
- //disable occlusion culling for reflection map for now
- S32 occlusion = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0;
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glClearColor(0,0,0,0);
+ S32 occlusion = LLPipeline::sUseOcclusion;
- mWaterRef.bindTarget();
+ //disable occlusion culling for reflection map for now
+ LLPipeline::sUseOcclusion = 0;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
- gGL.setColorMask(true, true);
- mWaterRef.clear();
- gGL.setColorMask(true, false);
+ if (!camera_is_underwater)
+ {
+ //generate planar reflection map
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
- mWaterRef.getViewport(gGLViewport);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
- stop_glerror();
+ mat.set_scale(glh::vec3f(1, 1, -1));
+ mat.set_translate(glh::vec3f(0,0,water_height*2.f));
+ mat = saved_modelview * mat;
- gGL.pushMatrix();
- mat.set_scale(glh::vec3f(1,1,-1));
- mat.set_translate(glh::vec3f(0,0,height*2.f));
+ mReflectionModelView = mat;
- glh::matrix4f current = glh_get_current_modelview();
+ set_current_modelview(mat);
+ gGL.loadMatrix(mat.m);
- mat = current * mat;
+ LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
- glh_set_current_modelview(mat);
- gGL.loadMatrix(mat.m);
+ glh::vec3f origin(0, 0, 0);
+ glh::matrix4f inv_mat = mat.inverse();
+ inv_mat.mult_matrix_vec(origin);
- LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
+ camera.setOrigin(origin.v);
- glh::matrix4f inv_mat = mat.inverse();
+ glCullFace(GL_FRONT);
- glh::vec3f origin(0,0,0);
- inv_mat.mult_matrix_vec(origin);
+ 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, -water_clip, &plane);
+ stateSort(camera, mReflectedObjects);
+ renderGeom(camera);
+ }
+ }
+ gPipeline.popRenderTypeMask();
+ }
+
+ mWaterRef.flush();
+ }
- camera.setOrigin(origin.v);
+ glCullFace(GL_BACK);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
- glCullFace(GL_FRONT);
+ set_current_modelview(saved_modelview);
+ }
- static LLCullResult ref_result;
+ //LLPipeline::sUseOcclusion = occlusion;
- if (LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- //initial sky pass (no user clip plane)
- { //mask out everything but the sky
- gPipeline.pushRenderTypeMask();
- gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
+ camera.setOrigin(camera_in.getOrigin());
+ //render distortion map
+ static bool last_update = true;
+ if (last_update)
+ {
+ gPipeline.pushRenderTypeMask();
- static LLCullResult result;
- updateCull(camera, result);
- stateSort(camera, result);
+ camera.setFar(camera_in.getFar());
+ clearRenderTypeMask(
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_GROUND,
+ END_RENDER_TYPES);
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- mWaterRef.flush();
+ // 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;
- gPipeline.grabReferences(result);
- gPipeline.mDeferredScreen.bindTarget();
- gGL.setColorMask(true, true);
- glClearColor(0,0,0,0);
- gPipeline.mDeferredScreen.clear();
+ 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);
- renderGeomDeferred(camera);
- }
- else
- {
- renderGeom(camera, TRUE);
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gPipeline.popRenderTypeMask();
- }
+ if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
+ {
+ LLPipeline::sDistortionRender = true;
- gGL.setColorMask(true, false);
- gPipeline.pushRenderTypeMask();
+ LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
+ glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
- 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);
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
- S32 detail = RenderReflectionDetail;
- if (detail > 0)
- { //mask out selected geometry based on reflection detail
+ mWaterDis.bindTarget();
+ mWaterDis.getViewport(gGLViewport);
- if (detail < 4)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (detail < 3)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
- if (detail < 2)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
- }
- }
- }
+ gGL.setColorMask(true, true);
+ mWaterDis.clear();
+ gGL.setColorMask(true, false);
+ F32 water_dist = water_height * LLPipeline::sDistortionWaterClipPlaneMargin;
- LLGLUserClipPlane clip_plane(plane, mat, projection);
- LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, ref_result, -water_clip, &plane);
- stateSort(camera, ref_result);
- }
+ //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(-pnorm, water_dist);
+ LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
- if (LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- if (RenderReflectionDetail > 0)
- {
- gPipeline.grabReferences(ref_result);
- LLGLUserClipPlane clip_plane(plane, mat, projection);
+ gGL.setColorMask(true, true);
+ mWaterDis.clear();
+ gGL.setColorMask(true, false);
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- renderGeomDeferred(camera);
- }
- else
- {
- renderGeom(camera);
- }
- }
- }
+ // ignore clip plane if we're underwater and viewing distortion map of objects above waterline
+ if (camera_is_underwater)
+ {
+ clip_plane.disable();
+ }
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- gPipeline.mDeferredScreen.flush();
- renderDeferredLightingToRT(&mWaterRef);
- }
+ if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
+ {
+ updateCull(camera, mRefractedObjects, water_clip, &plane);
+ stateSort(camera, mRefractedObjects);
+ renderGeom(camera);
+ }
- gPipeline.popRenderTypeMask();
- }
- glCullFace(GL_BACK);
- gGL.popMatrix();
- mWaterRef.flush();
- glh_set_current_modelview(current);
- LLPipeline::sUseOcclusion = occlusion;
- }
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
- camera.setOrigin(camera_in.getOrigin());
- //render distortion map
- static bool last_update = true;
- if (last_update)
- {
- camera.setFar(camera_in.getFar());
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- END_RENDER_TYPES);
- stop_glerror();
-
- LLPipeline::sUnderWaterRender = ! LLViewerCamera::getInstance()->cameraUnderWater();
+ LLWorld::getInstance()->renderPropertyLines();
- 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);
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.unbind();
+ }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLColor4& col = LLDrawPoolWater::sWaterFogColor;
- glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
- mWaterDis.bindTarget();
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
-
- mWaterDis.getViewport(gGLViewport);
-
- if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- //clip out geometry on the same side of water as the camera
- mat = glh_get_current_modelview();
- LLPlane plane(-pnorm, -(pd+pad));
-
- LLGLUserClipPlane clip_plane(plane, mat, projection);
- static LLCullResult result;
- updateCull(camera, result, water_clip, &plane);
- stateSort(camera, result);
+ mWaterDis.flush();
+ }
- gGL.setColorMask(true, true);
- mWaterDis.clear();
-
+ LLPipeline::sDistortionRender = false;
- gGL.setColorMask(true, false);
+ gPipeline.popRenderTypeMask();
+ }
+ last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
-
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- mWaterDis.flush();
- gPipeline.mDeferredScreen.bindTarget();
- gGL.setColorMask(true, true);
- glClearColor(0,0,0,0);
- gPipeline.mDeferredScreen.clear();
- gPipeline.grabReferences(result);
- renderGeomDeferred(camera);
- }
- else
- {
- renderGeom(camera);
+ gPipeline.popRenderTypeMask();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
-
- LLWorld::getInstance()->renderPropertyLines();
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
- }
+ LLPipeline::sUseOcclusion = occlusion;
+ LLPipeline::sUnderWaterRender = false;
+ LLPipeline::sReflectionRender = false;
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- gPipeline.mDeferredScreen.flush();
- renderDeferredLightingToRT(&mWaterDis);
- }
- }
+ LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
+ LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
- mWaterDis.flush();
- LLPipeline::sUnderWaterRender = false;
-
- }
- last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
+ if (!LLRenderTarget::sUseFBO)
+ {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ glClearColor(0.f, 0.f, 0.f, 0.f);
+ gViewerWindow->setup3DViewport();
- LLPipeline::sReflectionRender = false;
+ LLGLState::checkStates();
- if (!LLRenderTarget::sUseFBO)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- glClearColor(0.f, 0.f, 0.f, 0.f);
- gViewerWindow->setup3DViewport();
- gPipeline.popRenderTypeMask();
- LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
- LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
- LLPlane npnorm(-pnorm, -pd);
- LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
-
- LLGLState::checkStates();
-
- if (!skip_avatar_update)
- {
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
- }
+ if (!skip_avatar_update)
+ {
+ gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ }
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- }
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ }
}
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -10139,6 +9626,13 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_GEOM("Shadow Geom");
+
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked");
void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width)
{
@@ -10193,7 +9687,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGL.loadMatrix(proj.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- gGL.loadMatrix(gGLModelView);
+ gGL.loadMatrix(view.m);
stop_glerror();
gGLLastMatrix = NULL;
@@ -10202,6 +9696,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
stop_glerror();
+ LLEnvironment& environment = LLEnvironment::instance();
+
LLVertexBuffer::unbind();
{
@@ -10212,10 +9708,18 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
else
{
gDeferredShadowProgram.bind();
+ gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
gGL.diffuseColor4f(1,1,1,1);
+
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+
+ // if not using VSM, disable color writes
+ if (shadow_detail <= 2)
+ {
gGL.setColorMask(false, false);
+ }
LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
@@ -10233,41 +9737,69 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
if (use_shader)
{
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+
gDeferredShadowProgram.unbind();
renderGeomShadow(shadow_cam);
gDeferredShadowProgram.bind();
+ gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
else
{
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+
renderGeomShadow(shadow_cam);
}
{
LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
+
gDeferredShadowAlphaMaskProgram.bind();
gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ gDeferredShadowAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ }
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+ }
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
+ gDeferredShadowFullbrightAlphaMaskProgram.bind();
+ gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ }
mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_TREE);
gDeferredTreeShadowProgram.bind();
+ gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+ }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
+ }
//glCullFace(GL_BACK);
@@ -10511,7 +10043,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
gGL.setColorMask(true, true);
mHighlight.clear();
- if (canUseVertexShaders())
+ if (LLGLSLShader::sNoFixedFunction)
{
gHighlightProgram.bind();
}
@@ -10550,8 +10082,16 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
}
+LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
+{
+ return &mShadow[i];
+}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
+static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SETUP("Sun Shadow Setup");
+static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL("Render Dir");
+static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_SETUP("Spot Shadow Setup");
+static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render");
void LLPipeline::generateSunShadow(LLCamera& camera)
{
@@ -10590,6 +10130,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_BUMP,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_TREE,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_WATER,
@@ -10623,11 +10164,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
gGL.setColorMask(false, false);
+ LLEnvironment& environment = LLEnvironment::instance();
+
//get sun view matrix
//store current projection/modelview matrix
- glh::matrix4f saved_proj = glh_get_current_projection();
- glh::matrix4f saved_view = glh_get_current_modelview();
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_view = get_current_modelview();
glh::matrix4f inv_view = saved_view.inverse();
glh::matrix4f view[6];
@@ -10636,6 +10179,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//clip contains parallel split distances for 3 splits
LLVector3 clip = RenderShadowClipPlanes;
+ LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
+
//F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
//far clip on last split is minimum of camera view distance and 128
@@ -10652,11 +10197,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPlane shadow_near_clip;
{
LLVector3 p = gAgent.getPositionAgent();
- p += mSunDir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, mSunDir);
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
}
- LLVector3 lightDir = -mSunDir;
+ LLVector3 lightDir = -caster_dir;
lightDir.normVec();
glh::vec3f light_dir(lightDir.mV);
@@ -10731,8 +10276,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
update_min_max(min, max, fp[i]);
}
- near_clip = -max.mV[2];
- F32 far_clip = -min.mV[2]*2.f;
+ near_clip = llclamp(-max.mV[2], 0.01f, 4.0f);
+ F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f);
//far_clip = llmin(far_clip, 128.f);
far_clip = llmin(far_clip, camera.getFar());
@@ -10784,8 +10329,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
//restore render matrices
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
LLVector3 eye = camera.getOrigin();
@@ -11098,8 +10643,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
shadow_cam.setOrigin(0,0,0);
- glh_set_current_modelview(view[j]);
- glh_set_current_projection(proj[j]);
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
@@ -11112,8 +10657,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
0.f, 0.f, 0.5f, 0.5f,
0.f, 0.f, 0.f, 1.f);
- glh_set_current_modelview(view[j]);
- glh_set_current_projection(proj[j]);
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
for (U32 i = 0; i < 16; i++)
{
@@ -11123,8 +10668,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowModelview[j] = view[j];
mShadowProjection[j] = proj[j];
-
-
mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
stop_glerror();
@@ -11137,15 +10680,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
{
static LLCullResult result[4];
-
- renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
+ renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);
}
mShadow[j].flush();
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
mShadowCamera[j+4] = shadow_cam;
}
}
@@ -11192,8 +10733,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
for (S32 i = 0; i < 2; i++)
{
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
if (mShadowSpotLight[i].isNull())
{
@@ -11253,8 +10794,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
0.f, 0.f, 0.5f, 0.5f,
0.f, 0.f, 0.f, 1.f);
- glh_set_current_modelview(view[i+4]);
- glh_set_current_projection(proj[i+4]);
+ set_current_modelview(view[i+4]);
+ set_current_projection(proj[i+4]);
mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
@@ -11285,8 +10826,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ RenderSpotLight = drawable;
+
renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ RenderSpotLight = nullptr;
+
mShadow[i+4].flush();
}
}
@@ -11298,13 +10843,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (!CameraOffset)
{
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
}
else
{
- glh_set_current_modelview(view[1]);
- glh_set_current_projection(proj[1]);
+ set_current_modelview(view[1]);
+ set_current_projection(proj[1]);
gGL.loadMatrix(view[1].m);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.loadMatrix(proj[1].m);
@@ -11379,7 +10924,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (visually_muted || too_complex)
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ END_RENDER_TYPES);
}
else
{
@@ -11402,6 +10949,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_INVISIBLE,
@@ -11422,7 +10970,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);
markVisible(avatar->mDrawable, *viewer_camera);
- LLVOAvatar::sUseImpostors = false; // @TODO ???
LLVOAvatar::attachment_map_t::iterator iter;
for (iter = avatar->mAttachmentPoints.begin();
@@ -11482,7 +11029,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
F32 aspect = tdim.mV[0]/tdim.mV[1];
glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
- glh_set_current_projection(persp);
+ set_current_projection(persp);
gGL.loadMatrix(persp.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -11493,7 +11040,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
gGL.loadMatrix(mat.m);
- glh_set_current_modelview(mat);
+ set_current_modelview(mat);
glClearColor(0.0f,0.0f,0.0f,0.0f);
gGL.setColorMask(true, true);
@@ -11662,7 +11209,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
avatar->setImpostorDim(tdim);
- LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);
sUseOcclusion = occlusion;
sReflectionRender = false;
sImpostorRender = false;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 29fe1cbd33..0eaa6b141d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -61,14 +61,7 @@ bool compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn
bool LLRayAABB(const LLVector3 &center, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0);
bool setup_hud_matrices(); // use whole screen to render hud
bool setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking)
-glh::matrix4f glh_copy_matrix(F32* src);
-glh::matrix4f glh_get_current_modelview();
-void glh_set_current_modelview(const glh::matrix4f& mat);
-glh::matrix4f glh_get_current_projection();
-void glh_set_current_projection(glh::matrix4f& mat);
-glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar);
-glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);
-glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up);
+
extern LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY;
extern LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS;
@@ -91,6 +84,11 @@ extern LLTrace::BlockTimerStatHandle FTM_STATESORT;
extern LLTrace::BlockTimerStatHandle FTM_PIPELINE;
extern LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY;
+extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD;
+extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D;
+extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D;
+extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT;
+extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON;
class LLPipeline
{
@@ -102,10 +100,17 @@ public:
void restoreGL();
void resetVertexBuffers();
void doResetVertexBuffers(bool forced = false);
+ void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
+ void requestResizeShadowTexture(); // set flag only, no work, safer for callbacks...
+
void resizeScreenTexture();
+ void resizeShadowTexture();
+
void releaseGLBuffers();
void releaseLUTBuffers();
void releaseScreenBuffers();
+ void releaseShadowBuffers();
+
void createGLBuffers();
void createLUTBuffers();
@@ -127,13 +132,14 @@ public:
//attempt to allocate screen buffers at resX, resY
//returns true if allocation successful, false otherwise
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
+ bool allocateShadowBuffer(U32 resX, U32 resY);
void allocatePhysicsBuffer();
void resetVertexBuffers(LLDrawable* drawable);
void generateImpostor(LLVOAvatar* avatar);
void bindScreenToTexture();
- void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
+ void renderFinalize();
void init();
void cleanup();
@@ -213,6 +219,8 @@ public:
U32 addObject(LLViewerObject *obj);
void enableShadows(const bool enable_shadows);
+ void releaseShadowTargets();
+ void releaseShadowTarget(U32 index);
// void setLocalLighting(const bool local_lighting);
// bool isLocalLightingEnabled() const;
@@ -261,6 +269,7 @@ public:
void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
+ void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);
@@ -278,15 +287,17 @@ public:
void renderGeomDeferred(LLCamera& camera);
void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
void renderGeomShadow(LLCamera& camera);
- void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF);
+ void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
- void renderDeferredLighting();
- void renderDeferredLightingToRT(LLRenderTarget* target);
-
+ void renderDeferredLighting(LLRenderTarget* light_target);
+ void postDeferredGammaCorrect(LLRenderTarget* screen_target);
+
void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
+ LLRenderTarget* getShadowTarget(U32 i);
+
void generateHighlight(LLCamera& camera);
void renderHighlight(const LLViewerObject* obj, F32 fade);
void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; }
@@ -313,7 +324,7 @@ public:
void enableLightsAvatar();
void enableLightsPreview();
void enableLightsAvatarEdit(const LLColor4& color);
- void enableLightsFullbright(const LLColor4& color);
+ void enableLightsFullbright();
void disableLights();
void shiftObjects(const LLVector3 &offset);
@@ -398,14 +409,11 @@ public:
static bool getRenderHighlights();
static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
+ static void updateRenderTransparentWater();
static void updateRenderBump();
static void updateRenderDeferred();
static void refreshCachedSettings();
- static void throttleNewMemoryAllocation(bool disable);
-
-
-
void addDebugBlip(const LLVector3& position, const LLColor4& color);
void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -442,6 +450,7 @@ public:
RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
+ RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
@@ -566,6 +575,7 @@ public:
static bool sAutoMaskAlphaDeferred;
static bool sAutoMaskAlphaNonDeferred;
static bool sDisableShaders; // if true, rendering will be done without shaders
+ static bool sRenderTransparentWater;
static bool sRenderBump;
static bool sBakeSunlight;
static bool sNoAlpha;
@@ -576,6 +586,7 @@ public:
static bool sDynamicLOD;
static bool sPickAvatar;
static bool sReflectionRender;
+ static bool sDistortionRender;
static bool sImpostorRender;
static bool sImpostorRenderAlphaDepthPass;
static bool sUnderWaterRender;
@@ -585,10 +596,10 @@ public:
static bool sRenderAttachedLights;
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
- static bool sMemAllocationThrottled;
static S32 sVisibleLightCount;
static F32 sMinRenderSize;
static bool sRenderingHUDs;
+ static F32 sDistortionWaterClipPlaneMargin;
static LLTrace::EventStatHandle<S64> sStatBatchSize;
@@ -607,6 +618,10 @@ public:
LLRenderTarget mHighlight;
LLRenderTarget mPhysicsDisplay;
+ LLCullResult mSky;
+ LLCullResult mReflectedObjects;
+ LLCullResult mRefractedObjects;
+
//utility buffer for rendering post effects, gets abused by renderDeferredLighting
LLPointer<LLVertexBuffer> mDeferredVB;
@@ -625,22 +640,14 @@ public:
glh::matrix4f mSunShadowMatrix[6];
glh::matrix4f mShadowModelview[6];
glh::matrix4f mShadowProjection[6];
- glh::matrix4f mGIMatrix;
- glh::matrix4f mGIMatrixProj;
- glh::matrix4f mGIModelview;
- glh::matrix4f mGIProjection;
- glh::matrix4f mGINormalMatrix;
- glh::matrix4f mGIInvProj;
- LLVector2 mGIRange;
- F32 mGILightRadius;
-
- LLPointer<LLDrawable> mShadowSpotLight[2];
- F32 mSpotLightFade[2];
- LLPointer<LLDrawable> mTargetShadowSpotLight[2];
+ glh::matrix4f mReflectionModelView;
+
+ LLPointer<LLDrawable> mShadowSpotLight[2];
+ F32 mSpotLightFade[2];
+ LLPointer<LLDrawable> mTargetShadowSpotLight[2];
LLVector4 mSunClipPlanes;
LLVector4 mSunOrthoClipPlanes;
-
LLVector2 mScreenScale;
//water reflection texture
@@ -649,6 +656,8 @@ public:
//water distortion texture (refraction)
LLRenderTarget mWaterDis;
+ LLRenderTarget mBake;
+
//texture for making the glow
LLRenderTarget mGlow[3];
@@ -657,9 +666,14 @@ public:
U32 mTrueNoiseMap;
U32 mLightFunc;
- LLColor4 mSunDiffuse;
- LLVector3 mSunDir;
- LLVector3 mTransformedSunDir;
+ LLColor4 mSunDiffuse;
+ LLColor4 mMoonDiffuse;
+ LLVector4 mSunDir;
+ LLVector4 mMoonDir;
+ bool mNeedsShadowTargetClear;
+
+ LLVector4 mTransformedSunDir;
+ LLVector4 mTransformedMoonDir;
bool mInitialized;
bool mVertexShadersEnabled;
@@ -864,7 +878,6 @@ public:
//cached settings
static bool WindLightUseAtmosShaders;
- static bool VertexShaderEnable;
static bool RenderAvatarVP;
static bool RenderDeferred;
static F32 RenderDeferredSunWash;
@@ -920,6 +933,7 @@ public:
static F32 RenderShadowBias;
static F32 RenderSpotShadowOffset;
static F32 RenderSpotShadowBias;
+ static LLDrawable* RenderSpotLight;
static F32 RenderEdgeDepthCutoff;
static F32 RenderEdgeNormCutoff;
static LLVector3 RenderShadowGaussian;
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index 8587243791..ff2d8b4943 100755
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -155,7 +155,7 @@ BEGIN
VALUE "FileDescription", "Second Life"
VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
VALUE "InternalName", "Second Life"
- VALUE "LegalCopyright", "Copyright � 2001, Linden Research, Inc."
+ VALUE "LegalCopyright", "Copyright (c) 2020, Linden Research, Inc."
VALUE "OriginalFilename", "SecondLife.exe"
VALUE "ProductName", "Second Life"
VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
diff --git a/indra/newview/roles_constants.h b/indra/newview/roles_constants.h
index 24792dd731..fecf5f9d4a 100644
--- a/indra/newview/roles_constants.h
+++ b/indra/newview/roles_constants.h
@@ -52,7 +52,6 @@ enum LLRoleChangeType
//
// KNOWN HOLES: use these for any single bit powers you need
-// bit 0x1 << 46
// bit 0x1 << 52 and above
// These powers were removed to make group roles simpler
@@ -103,6 +102,7 @@ const U64 GP_LAND_ALLOW_CREATE = 0x1LL << 25; // Bypass Create/Edit Objects Re
const U64 GP_LAND_ALLOW_LANDMARK = 0x1LL << 26; // Bypass Landmark Restriction
const U64 GP_LAND_ALLOW_SET_HOME = 0x1LL << 28; // Bypass Set Home Point Restriction
const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land
+const U64 GP_LAND_ALLOW_ENVIRONMENT = 0x1LL << 46; // Allowed to change the environment
// Parcel Access
const U64 GP_LAND_MANAGE_ALLOWED = 0x1LL << 29; // Manage Allowed List
@@ -164,6 +164,7 @@ const U64 GP_DEFAULT_OFFICER = GP_DEFAULT_MEMBER // Superset of GP_DEFAULT_MEMBE
| GP_LAND_ALLOW_EDIT_LAND
| GP_LAND_ALLOW_FLY
| GP_LAND_ALLOW_CREATE
+ | GP_LAND_ALLOW_ENVIRONMENT
| GP_LAND_ALLOW_LANDMARK
| GP_LAND_CHANGE_IDENTITY
| GP_LAND_CHANGE_MEDIA
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index e0da7f5d9e..7beb013fba 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -42,6 +42,9 @@
name="Gray"
value="0.5 0.5 0.5 1" />
<color
+ name="DkGray0"
+ value="0.27 0.27 0.27 1" />
+ <color
name="DkGray"
value="0.125 0.125 0.125 1" />
<color
@@ -334,6 +337,9 @@
name="ContextSilhouetteColor"
reference="EmphasisColor" />
<color
+ name="ConversationFriendColor"
+ value="0.42 0.85 0.71 1" />
+ <color
name="DefaultHighlightDark"
reference="White_10" />
<color
@@ -848,6 +854,9 @@
name="ColorSwatchBorderColor"
value="0.45098 0.517647 0.607843 1"/>
<color
+ name="ChatTeleportSeparatorColor"
+ reference="Black" />
+ <color
name="ChatTimestampColor"
reference="White" />
<color
@@ -957,4 +966,7 @@
<color
name="OutfitGalleryItemUnselected"
value="0.4 0.4 0.4 1" />
+ <color
+ name="AddPaymentPanel"
+ value="0.27 0.27 0.27 1" />
</colors>
diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
new file mode 100644
index 0000000000..5a50e0ad34
--- /dev/null
+++ b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png
new file mode 100644
index 0000000000..ff1ea3a72e
--- /dev/null
+++ b/indra/newview/skins/default/textures/3p_icons/havok_logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
new file mode 100644
index 0000000000..6f20e87b7a
--- /dev/null
+++ b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png
new file mode 100644
index 0000000000..ffc3c85ea2
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png
new file mode 100644
index 0000000000..2812d614e6
--- /dev/null
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Flashing.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Flashing.png
new file mode 100644
index 0000000000..fd13bb699d
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Flashing.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Settings.png b/indra/newview/skins/default/textures/icons/Inv_Settings.png
new file mode 100644
index 0000000000..c43ba349c4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Settings.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png b/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png
new file mode 100644
index 0000000000..258ade1327
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_SettingsDay.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png b/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png
new file mode 100644
index 0000000000..77858b23c3
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_SettingsSky.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png b/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png
new file mode 100644
index 0000000000..46fb58c3f2
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_SettingsWater.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png
new file mode 100644
index 0000000000..048da25c92
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Presets_Icon.png b/indra/newview/skins/default/textures/icons/Presets_Icon.png
index 5a6628816b..503ee892a5 100644
--- a/indra/newview/skins/default/textures/icons/Presets_Icon.png
+++ b/indra/newview/skins/default/textures/icons/Presets_Icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Presets_Icon_Graphic.png b/indra/newview/skins/default/textures/icons/Presets_Icon_Graphic.png
new file mode 100644
index 0000000000..5a6628816b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Presets_Icon_Graphic.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Landmarks.png b/indra/newview/skins/default/textures/navbar/Landmarks.png
new file mode 100644
index 0000000000..2b35de913b
--- /dev/null
+++ b/indra/newview/skins/default/textures/navbar/Landmarks.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 7482ec994c..03878d9fe7 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -45,6 +45,10 @@ with the same filename but different name
<texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" />
<texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" />
+ <texture name="add_payment_image_center" file_name="windows/add_payment_image_center.png" preload="true" />
+ <texture name="add_payment_image_left" file_name="windows/add_payment_image_left.png" preload="true" />
+ <texture name="add_payment_image_right" file_name="windows/add_payment_image_right.png" preload="true" />
+
<texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" />
<texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" />
@@ -98,7 +102,7 @@ with the same filename but different name
<texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" />
<texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
- <texture name="Cam_Avatar_Off" file_name="bottomtray/Cam_Avatar_Off.png" preload="false" />
+ <texture name="Cam_Avatar_Off" file_name="bottomtray/Cam_Avatar_Off.png" preload="true" />
<texture name="Cam_FreeCam_Off" file_name="bottomtray/Cam_FreeCam_Off.png" preload="false" />
<texture name="Cam_Orbit_Off" file_name="bottomtray/Cam_Orbit_Off.png" preload="false" />
<texture name="Cam_Pan_Off" file_name="bottomtray/Cam_Pan_Off.png" preload="false" />
@@ -113,8 +117,10 @@ with the same filename but different name
<texture name="Cam_Rotate_In" file_name="bottomtray/Cam_Rotate_In.png" preload="false" />
<texture name="Cam_Rotate_Out" file_name="bottomtray/Cam_Rotate_Out.png" preload="false" />
+ <texture name="Cam_Rotate_Center" file_name="bottomtray/Cam_Rotate_Center.png" preload="false" />
<texture name="Cam_Tracking_In" file_name="bottomtray/Cam_Tracking_In.png" preload="false" />
<texture name="Cam_Tracking_Out" file_name="bottomtray/Cam_Tracking_Out.png" preload="false" />
+ <texture name="Cam_Tracking_Center" file_name="bottomtray/Cam_Tracking_Center.png" preload="false" />
<texture name="Checkbox_Off_Disabled" file_name="widgets/Checkbox_Disabled.png" preload="true" />
<texture name="Checkbox_On_Disabled" file_name="widgets/Checkbox_On_Disabled.png" preload="true" />
@@ -143,7 +149,7 @@ with the same filename but different name
<texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" />
<texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" />
<texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" />
- <texture name="Command_Outbox_Icon" file_name="toolbar_icons/outbox.png" preload="true" />
+ <texture name="Command_Environments_Icon" file_name="toolbar_icons/environments.png" preload="true" />
<texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" />
<texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" />
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
@@ -204,7 +210,9 @@ with the same filename but different name
<texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
- <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
+ <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" />
+ <texture name="Presets_Icon_Graphic" file_name="icons/Presets_Icon_Graphic.png" preload="true" />
+ <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
<texture name="Favorite_Star_Over" file_name="navbar/Favorite_Star_Over.png" preload="false" />
@@ -253,6 +261,7 @@ with the same filename but different name
<texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" />
<texture name="Icon_Gear_Foreground" file_name="windows/Icon_Gear_Foreground.png" preload="false" />
<texture name="Icon_Gear_Press" file_name="windows/Icon_Gear_Press.png" preload="false" />
+ <texture name="Icon_Gear" file_name="windows/Icon_Gear.png" preload="false" />
<texture name="Icon_Help_Foreground" file_name="windows/Icon_Help_Foreground.png" preload="true" />
<texture name="Icon_Help_Press" file_name="windows/Icon_Help_Press.png" preload="true" />
@@ -319,11 +328,20 @@ with the same filename but different name
<texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
<texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
<texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />
+ <texture name="Inv_Settings" file_name="icons/Inv_Settings.png" preload="false" />
+ <texture name="Inv_SettingsSky" file_name="icons/Inv_SettingsSky.png" preload="false" />
+ <texture name="Inv_SettingsWater" file_name="icons/Inv_SettingsWater.png" preload="false" />
+ <texture name="Inv_SettingsDay" file_name="icons/Inv_SettingsDay.png" preload="false" />
+
<texture name="Inv_Invalid" file_name="icons/Inv_Invalid.png" preload="false" />
<texture name="Inv_Unknown" file_name="icons/Inv_UnknownObject.png" preload="false" />
<texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" />
<texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" />
-
+
+ <texture name="Inv_Toolbar_SearchVisibility" file_name="icons/Inv_Toolbar_SearchVisibility.png" preload="false" />
+
+ <texture name="Landmarks_overlay" file_name="navbar/Landmarks.png" preload="false" />
+
<texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
<texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
@@ -487,6 +505,7 @@ with the same filename but different name
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
<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" />
<texture name="PushButton_Disabled" file_name="widgets/PushButton_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
@@ -588,7 +607,6 @@ with the same filename but different name
<texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" />
<texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" />
<texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" />
-
<texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" />
<texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" />
@@ -624,6 +642,7 @@ with the same filename but different name
<texture name="TabTop_Right_Off" file_name="containers/TabTop_Right_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" />
<texture name="TabTop_Right_Selected" file_name="containers/TabTop_Right_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" />
+ <texture name="TabTop_Right_Flashing" file_name="containers/TabTop_Right_Flashing.png" preload="false" scale.left="8" scale.top="8" scale.right="62" scale.bottom="9" />
<texture name="TabTop_Middle_Off" file_name="containers/TabTop_Middle_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" />
<texture name="TabTop_Middle_Selected" file_name="containers/TabTop_Middle_Selected.png" preload="false" scale.left="8" scale.top="8" scale.right="96" scale.bottom="9" />
<texture name="TabTop_Left_Off" file_name="containers/TabTop_Left_Off.png" preload="false" scale.left="8" scale.top="8" scale.right="120" scale.bottom="9" />
@@ -638,6 +657,7 @@ with the same filename but different name
<texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
<texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
<texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
+ <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
<texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" />
@@ -679,6 +699,20 @@ with the same filename but different name
<texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120" scale_type="scale_outer"/>
+ <texture name="VirtualTrackball_Moon_Back" file_name="widgets/track_control_moon_back.png" />
+ <texture name="VirtualTrackball_Moon_Front" file_name="widgets/track_control_moon_front.png" />
+ <texture name="VirtualTrackball_Rotate_Bottom" file_name="widgets/track_control_rotate_bottom.png" />
+ <texture name="VirtualTrackball_Rotate_Left" file_name="widgets/track_control_rotate_left_side.png" />
+ <texture name="VirtualTrackball_Rotate_Right" file_name="widgets/track_control_rotate_right_side.png" />
+ <texture name="VirtualTrackball_Rotate_Top" file_name="widgets/track_control_rotate_top.png" />
+ <texture name="VirtualTrackball_Rotate_Bottom_Active" file_name="widgets/track_control_rotate_bottom_active.png" />
+ <texture name="VirtualTrackball_Rotate_Left_Active" file_name="widgets/track_control_rotate_left_side_active.png" />
+ <texture name="VirtualTrackball_Rotate_Right_Active" file_name="widgets/track_control_rotate_right_side_active.png" />
+ <texture name="VirtualTrackball_Rotate_Top_Active" file_name="widgets/track_control_rotate_top_active.png" />
+ <texture name="VirtualTrackball_Sphere" file_name="widgets/track_control_sphere.png" />
+ <texture name="VirtualTrackball_Sun_Back" file_name="widgets/track_control_sun_back.png" />
+ <texture name="VirtualTrackball_Sun_Front" file_name="widgets/track_control_sun_front.png" />
+
<texture name="Volume_Background" file_name="windows/Volume_Background.png" preload="false"
scale.left="6" scale.top="33" scale.right="63" scale.bottom="10" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/environments.png b/indra/newview/skins/default/textures/toolbar_icons/environments.png
new file mode 100644
index 0000000000..620db9f793
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/environments.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png b/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png
new file mode 100644
index 0000000000..ec0926bfa1
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
index b627232012..8888e134d1 100644
--- a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png
new file mode 100644
index 0000000000..e3944289c6
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_moon_back.png b/indra/newview/skins/default/textures/widgets/track_control_moon_back.png
new file mode 100644
index 0000000000..30f538d35b
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_moon_back.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_moon_front.png b/indra/newview/skins/default/textures/widgets/track_control_moon_front.png
new file mode 100644
index 0000000000..d3882c5e4c
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_moon_front.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom.png
new file mode 100644
index 0000000000..232c812aae
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom_active.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom_active.png
new file mode 100644
index 0000000000..911618b08e
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_bottom_active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side.png
new file mode 100644
index 0000000000..bcc78fc5e4
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side_active.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side_active.png
new file mode 100644
index 0000000000..2fe04b93f1
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_left_side_active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side.png
new file mode 100644
index 0000000000..d0827abf28
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side_active.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side_active.png
new file mode 100644
index 0000000000..824051562f
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_right_side_active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_top.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_top.png
new file mode 100644
index 0000000000..13a5e9c2e8
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_top.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_rotate_top_active.png b/indra/newview/skins/default/textures/widgets/track_control_rotate_top_active.png
new file mode 100644
index 0000000000..9a7493703b
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_rotate_top_active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_sphere.png b/indra/newview/skins/default/textures/widgets/track_control_sphere.png
new file mode 100644
index 0000000000..a13b7725ea
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_sphere.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_sun_back.png b/indra/newview/skins/default/textures/widgets/track_control_sun_back.png
new file mode 100644
index 0000000000..23c89068f8
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_sun_back.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/track_control_sun_front.png b/indra/newview/skins/default/textures/widgets/track_control_sun_front.png
new file mode 100644
index 0000000000..6dfdc04423
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/track_control_sun_front.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear.png b/indra/newview/skins/default/textures/windows/Icon_Gear.png
new file mode 100644
index 0000000000..e1e89b8f32
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_center.png b/indra/newview/skins/default/textures/windows/add_payment_image_center.png
new file mode 100644
index 0000000000..b5459136cb
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/add_payment_image_center.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_left.png b/indra/newview/skins/default/textures/windows/add_payment_image_left.png
new file mode 100644
index 0000000000..7fb65e724a
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/add_payment_image_left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_right.png b/indra/newview/skins/default/textures/windows/add_payment_image_right.png
new file mode 100644
index 0000000000..f1937b6318
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/add_payment_image_right.png
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
index 1fa10fde53..77904d7d12 100644
--- a/indra/newview/skins/default/textures/windows/first_login_image_left.png
+++ b/indra/newview/skins/default/textures/windows/first_login_image_left.png
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
index d764d846b7..35ecce9c07 100644
--- a/indra/newview/skins/default/textures/windows/first_login_image_right.png
+++ b/indra/newview/skins/default/textures/windows/first_login_image_right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/login_sl_logo.png b/indra/newview/skins/default/textures/windows/login_sl_logo.png
index 9810d00237..1eede80c83 100644
--- a/indra/newview/skins/default/textures/windows/login_sl_logo.png
+++ b/indra/newview/skins/default/textures/windows/login_sl_logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/login_sl_logo_small.png b/indra/newview/skins/default/textures/windows/login_sl_logo_small.png
index 0a245442d5..c5933001f0 100644
--- a/indra/newview/skins/default/textures/windows/login_sl_logo_small.png
+++ b/indra/newview/skins/default/textures/windows/login_sl_logo_small.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/floater_buy_currency.xml b/indra/newview/skins/default/xui/da/floater_buy_currency.xml
index 3c0428b2b0..b7ac181dd4 100644
--- a/indra/newview/skins/default/xui/da/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_currency.xml
@@ -60,8 +60,7 @@ objektet.
</text>
<button label="Køb nu" name="buy_btn"/>
<button label="Annullér" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
Kan ikke købe
- </text>
- <button label="Fortsæt til web" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
index 9d7fc0f223..37e9351ab5 100644
--- a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Berør" name="touch_attach" />
+ <menu_item_call label="Redigér" name="edit_item" />
<menu_item_call label="Tag af" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/da/menu_inventory.xml b/indra/newview/skins/default/xui/da/menu_inventory.xml
index f9bdf36f1f..ba96d6dca1 100644
--- a/indra/newview/skins/default/xui/da/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory.xml
@@ -78,6 +78,7 @@
<menu_item_call label="Tag på" name="Wearable And Object Wear"/>
<menu label="Vedhæft" name="Attach To"/>
<menu label="Vedhæft til HUD" name="Attach To HUD"/>
+ <menu_item_call label="Berør" name="Attachment Touch" />
<menu_item_call label="Redigér" name="Wearable Edit"/>
<menu_item_call label="Tilføj" name="Wearable Add"/>
<menu_item_call label="Tag af" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
index 63f4b0b388..67adf74bcd 100644
--- a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Erstat" name="wear_replace"/>
<menu_item_call label="Tag på" name="wear_wear"/>
<menu_item_call label="Tilføj" name="wear_add"/>
+ <menu_item_call label="Berør" name="touch" />
<menu_item_call label="Tag af" name="take_off_or_detach"/>
<menu_item_call label="Tag af" name="detach"/>
<context_menu label="Vedhæft til" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
index 515a15b287..ff58cd68b2 100644
--- a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="Gear Wearing">
- <menu_item_call label="Redigér sæt" name="edit"/>
+ <menu_item_call label="Berør" name="touch"/>
+ <menu_item_call label="Redigér" name="edit_item"/>
+ <menu_item_call label="Redigér sæt" name="edit_outfit"/>
<menu_item_call label="Tag af" name="takeoff"/>
</menu>
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
index c0db7b6842..adaac35f68 100644
--- a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Berør" name="touch_attach"/>
+ <menu_item_call label="Redigér" name="edit_item"/>
<menu_item_call label="Tag af" name="take_off"/>
<menu_item_call label="Tag af" name="detach"/>
- <menu_item_call label="Redigér sæt" name="edit"/>
+ <menu_item_call label="Redigér sæt" name="edit_outfit"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
index e494b2b755..c7770eb81b 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
@@ -29,7 +29,6 @@
<check_box initial_value="true" label="Gennemsigtig vand" name="TransparentWater"/>
<check_box initial_value="true" label="Glatte flader og skin" name="BumpShiny"/>
<check_box initial_value="true" label="Lokale lys" name="LocalLights"/>
- <check_box initial_value="true" label="Basale flader" name="BasicShaders" tool_tip="Ved at slå dette valg fra, kan det forhindres at visse grafikkort drivere crasher."/>
<check_box initial_value="true" label="Atmosfæriske flader" name="WindLightUseAtmosShaders"/>
<check_box initial_value="true" label="Lys og skygger" name="UseLightShaders"/>
<check_box initial_value="true" label="&quot;Ambient Occlusion&quot;" name="UseSSAO"/>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index eee3dc2c77..ec6ba4800d 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -560,6 +560,9 @@ Prøv venligst om lidt igen.
<string name="mesh">
mesh
</string>
+ <string name="settings">
+ indstillinger
+ </string>
<string name="AvatarEditingAppearance">
(Redigering Udseende)
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 4dd64cba2a..8f55b3297f 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -30,7 +30,7 @@
<floater.string name="Always">
Immer
</floater.string>
- <tab_container name="landtab" tab_min_width="40" width="489">
+ <tab_container name="landtab" tab_min_width="40">
<panel label="ALLGEMEIN" name="land_general_panel">
<panel.string name="new users only">
Nur neue Benutzer
diff --git a/indra/newview/skins/default/xui/de/floater_adjust_environment.xml b/indra/newview/skins/default/xui/de/floater_adjust_environment.xml
new file mode 100644
index 0000000000..776a866077
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Persönliche Beleuchtung">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Zurücksetzen" name="btn_reset" tool_tip="Schließen und auf gemeinsame Umgebung zurücksetzen"/>
+ <text name="cloud_map_label">
+ Wolkenbild:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Sonne:
+ </text>
+ <check_box label="Beacon anzeigen" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Beacon anzeigen" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_beacons.xml b/indra/newview/skins/default/xui/de/floater_beacons.xml
index 1a052bd814..c44cd407de 100644
--- a/indra/newview/skins/default/xui/de/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/de/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Soundquellen" name="sounds"/>
<check_box label="Partikelquellen" name="particles"/>
<check_box label="Medienquellen" name="moapbeacon"/>
+ <check_box label="Sonne" name="sun"/>
+ <check_box label="Mond" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
index 9454933264..7a3fa41a24 100644
--- a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="Sounds"/>
<check_box label="Texturen" name="check_texture"/>
<icon name="icon_texture" tool_tip="Texturen"/>
+ <icon name="icon_setting" tool_tip="Umgebungseinstellungen"/>
<button label="√ Alle" label_selected="Alle" name="check_all"/>
<button label="Löschen" label_selected="Keine" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
index 65926c088c..eb94df1cad 100644
--- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="Jetzt kaufen" name="buy_btn"/>
<button label="Abbrechen" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
Kaufabbruch
- </text>
- <button label="Weiter zur Kontoseite" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
deleted file mode 100644
index ae7d5ef77d..0000000000
--- a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="UMGEB.-VOREINST. LÖSCHEN">
- <string name="title_water">
- Wasser-Voreinstellung löschen
- </string>
- <string name="title_sky">
- Himmel-Voreinstellung löschen
- </string>
- <string name="title_day_cycle">
- Tageszyklus löschen
- </string>
- <string name="label_water">
- Voreinstellung:
- </string>
- <string name="label_sky">
- Voreinstellung:
- </string>
- <string name="label_day_cycle">
- Tageszyklus:
- </string>
- <string name="msg_confirm_deletion">
- Möchten Sie die ausgewählte Voreinstellung wirklich löschen?
- </string>
- <string name="msg_sky_is_referenced">
- Eine Voreinstellung, auf die sich ein Tageszyklus bezieht, kann nicht gelöscht werden.
- </string>
- <string name="combo_label">
- -Voreinstellung auswählen-
- </string>
- <text name="label">
- Voreinstellung:
- </text>
- <button label="Löschen" name="delete"/>
- <button label="Abbrechen" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/de/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..c21eec1893
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Tageszyklus bearbeiten">
+ <string name="title_new">
+ Neuen Tageszyklus erstellen
+ </string>
+ <string name="title_edit">
+ Tageszyklus bearbeiten
+ </string>
+ <string name="hint_new">
+ Geben Sie einen Namen für Ihren Tageszyklus ein, passen Sie die Steuerungen an, um den Tageszyklus zu erstellen, und klicken Sie auf &quot;Speichern&quot;.
+ </string>
+ <string name="hint_edit">
+ Um Ihren Tageszyklus zu bearbeiten, passen Sie die unten angezeigten Steuerungen an und klicken Sie auf „Speichern“.
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Himmel [ALT]
+ </string>
+ <string name="sky_label">
+ Himmel
+ </string>
+ <string name="water_label">
+ Wasser
+ </string>
+ <string name="commit_parcel">
+ Auf Parzelle anwenden
+ </string>
+ <string name="commit_region">
+ Auf Region anwenden
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Name des Tageszyklus:
+ </text>
+ <button label="Importieren" name="btn_import" tool_tip="Alte Einstellungen von Datenträger importieren."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Himmel 4" name="sky4_track"/>
+ <button label="Himmel 3" name="sky3_track"/>
+ <button label="Himmel 2" name="sky2_track"/>
+ <button label="Bodenhöhe" name="sky1_track"/>
+ <button label="Wasser" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Pfad klonen von" name="copy_track"/>
+ <button label="Pfad laden von" name="load_track"/>
+ <button label="Pfad löschen" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Schritt vor"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Schritt zurück"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="[FRAME] hinzufügen" name="add_frame"/>
+ <button label="[FRAME] laden" name="btn_load_frame"/>
+ <button label="[FRAME] löschen" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Wählen Sie einen Schlüssel-Frame aus der obigen Zeitlinie, um die Einstellungen zu bearbeiten.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Wasser" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmosphäre und Beleuchtung" name="atmosphere_panel"/>
+ <panel label="Wolken" name="clouds_panel"/>
+ <panel label="Sonne und Mond" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Speichern" name="save_btn"/>
+ <button label="Abbrechen" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/de/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..c18e333571
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Festgelegte Umgebung">
+ <string name="edit_sky">
+ Himmel bearbeiten:
+ </string>
+ <string name="edit_water">
+ Wasser bearbeiten:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Laden" name="btn_load" tool_tip="Einstellungen aus dem Inventar laden"/>
+ <button label="Importieren" name="btn_import" tool_tip="Alte Einstellungen von Datenträger importieren."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Speichern" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Abbrechen" name="btn_cancel" tool_tip="Zur zuletzt gespeicherten Version zurückkehren"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
index cdacabec90..b361b88aa8 100644
--- a/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
@@ -12,6 +12,7 @@
<check_box label="Sounds" name="check_sound"/>
<check_box label="Texturen" name="check_texture"/>
<check_box label="Fotos" name="check_snapshot"/>
+ <check_box label="Einstellungen" name="check_settings"/>
<button label="Alle" label_selected="Alle" name="All"/>
<button label="Keine" label_selected="Keine" name="None"/>
<check_box label="Ordner immer anzeigen" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
deleted file mode 100644
index 4070dee84c..0000000000
--- a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="HÄNDLER-OUTBOX">
- <string name="OutboxFolderCount1">
- 1 Ordner
- </string>
- <string name="OutboxFolderCountN">
- [NUM] Ordner
- </string>
- <string name="OutboxImporting">
- Ordner übertragen...
- </string>
- <string name="OutboxInitializing">
- Initialisieren...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Laden...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Artikel hierher ziehen, um Ordner zu erstellen
- </text>
- </panel>
- <button label="In Marktplatz übertragen" name="outbox_import_btn" tool_tip="In meinen Marktplatz-Laden verschieben"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_my_environments.xml b/indra/newview/skins/default/xui/de/floater_my_environments.xml
new file mode 100644
index 0000000000..ff5556304a
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Orte" name="my_environments" title="MEINE UMGEBUNGEN">
+ <layout_stack>
+ <layout_panel label="Filter" name="filter_panel">
+ <check_box label="Tage" name="chk_days"/>
+ <check_box label="Himmel" name="chk_skies"/>
+ <check_box label="Wasser" name="chk_water"/>
+ <filter_editor label="Umgebungen filtern" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Umgebungen" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Alle Ordner anzeigen" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Weitere Optionen"/>
+ <menu_button name="btn_newsettings" tool_tip="Neue Einstellung erstellen"/>
+ <button name="btn_del" tool_tip="Ausgewähltes Objekt löschen"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_perms_default.xml b/indra/newview/skins/default/xui/de/floater_perms_default.xml
index 6274739f70..a9b845611a 100644
--- a/indra/newview/skins/default/xui/de/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/de/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Standardberechtigungen für die Erstellung von Kleidungsstücken und Körperteilen festlegen">
Tragbare Objekte
</text>
+ <text name="label_13" tool_tip="Standardberechtigungen für die Erstellung von Umgebungseinstellungen festlegen">
+ Einstellungen
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Abbrechen" label_selected="Abbrechen" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/de/floater_pick_track.xml b/indra/newview/skins/default/xui/de/floater_pick_track.xml
new file mode 100644
index 0000000000..d5a565a2b0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="AUSWÄHLEN: PFAD">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Ursprungshimmel auswählen:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Himmel4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Himmel3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Himmel2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Boden" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml
index 41e8dc5ef4..cd514f5afd 100644
--- a/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/de/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Transparentes Wasser" name="TransparentWater"/>
<check_box initial_value="true" label="Bumpmapping und Glanz" name="BumpShiny"/>
<check_box initial_value="true" label="Lokale Lichtquellen" name="LocalLights"/>
- <check_box initial_value="true" label="Einfache Shader" name="BasicShaders" tool_tip="Deaktivieren Sie diese Option, wenn der Grafikkartentreiber Abstürze verursacht"/>
<slider label="Terraindetails:" name="TerrainDetail"/>
<text name="TerrainDetailText">
Niedrig
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 526c0813bd..eacd11c3e6 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
@@ -13,7 +13,7 @@
[WIDTH]px x [HEIGHT]px
</text>
<text name="aspect_ratio">
- Seitenverhältnis anzeigen
+ Vorschau Seitenverhältnis
</text>
<combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen">
<combo_item name="Unconstrained">
diff --git a/indra/newview/skins/default/xui/de/floater_settings_picker.xml b/indra/newview/skins/default/xui/de/floater_settings_picker.xml
new file mode 100644
index 0000000000..1fe417bdee
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="AUSWÄHLEN: EINSTELLUNGEN">
+ <floater.string name="pick title">
+ Auswahl:
+ </floater.string>
+ <floater.string name="pick_track">
+ PFAD AUSWÄHLEN
+ </floater.string>
+ <floater.string name="pick_settings">
+ EINSTELLUNGEN AUSWÄHLEN
+ </floater.string>
+ <floater.string name="track_water">
+ Wasser
+ </floater.string>
+ <floater.string name="track_ground">
+ Boden
+ </floater.string>
+ <floater.string name="track_sky">
+ Himmel[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Texturen filtern" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
index b794d879f0..81b093b8c2 100644
--- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
@@ -9,18 +9,14 @@
<text name="Multiple">
Mehrere Texturen
</text>
- <radio_group name="mode_selection">
- <radio_item label="Inventar" name="inventory" value="0"/>
- <radio_item label="Lokal" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Größe: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Inventar" name="inventory" value="0"/>
+ <combo_box.item label="Lokal" name="local" value="1"/>
+ </combo_box>
<button label="Standard" label_selected="Standard" name="Default"/>
<button label="Leer" label_selected="Leer" name="Blank"/>
<button label="Keine" label_selected="Keine" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <check_box initial_value="true" label="Jetzt übernehmen" name="apply_immediate_check"/>
<text name="preview_disabled" value="Vorschau deaktiviert"/>
<filter_editor label="Texturen filtern" name="inventory search editor"/>
<check_box initial_value="false" label="Ordner anzeigen" name="show_folders_check"/>
@@ -31,6 +27,22 @@
<column label="Name" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Back-Textur auswählen">
+ <combo_box.item label="Keine" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Basis-Mesh-Region verbergen" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>
+ <check_box initial_value="true" label="Jetzt übernehmen" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
index 05d3dfca9d..7c7da58866 100644
--- a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Berühren" name="touch_attach" />
+ <menu_item_call label="Bearbeiten" name="edit_item" />
<menu_item_call label="Abnehmen" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml
index e02d464a3d..743b8b2073 100644
--- a/indra/newview/skins/default/xui/de/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Aktivieren" name="Marketplace Activate"/>
<menu_item_call label="Deaktivieren" name="Marketplace Deactivate"/>
<menu_item_call label="Teilen" name="Share"/>
- <menu_item_call label="Kaufen" name="Task Buy"/>
<menu_item_call label="Öffnen" name="Task Open"/>
<menu_item_call label="Abspielen" name="Task Play"/>
<menu_item_call label="Eigenschaften" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Neue Unterhose" name="New Underpants"/>
<menu_item_call label="Neue Alpha-Maske" name="New Alpha Mask"/>
<menu_item_call label="Neue Tätowierung" name="New Tattoo"/>
+ <menu_item_call label="Neues Universal" name="New Universal"/>
<menu_item_call label="Neue Physik" name="New Physics"/>
</menu>
<menu label="Neue Körperteile" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Neues Haar" name="New Hair"/>
<menu_item_call label="Neue Augen" name="New Eyes"/>
</menu>
+ <menu label="Neue Einstellungen" name="New Settings">
+ <menu_item_call label="Neuer Himmel" name="New Sky"/>
+ <menu_item_call label="Neues Wasser" name="New Water"/>
+ <menu_item_call label="Neuer Tageszyklus" name="New Day Cycle"/>
+ </menu>
<menu label="Als Standard verwenden für" name="upload_def">
<menu_item_call label="Hochgeladene Bilder" name="Image uploads"/>
<menu_item_call label="Hochgeladene Sounds" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Anziehen" name="Wearable And Object Wear"/>
<menu label="Anhängen an" name="Attach To"/>
<menu label="An HUD hängen" name="Attach To HUD"/>
+ <menu_item_call label="Berühren" name="Attachment Touch" />
<menu_item_call label="Bearbeiten" name="Wearable Edit"/>
<menu_item_call label="Hinzufügen" name="Wearable Add"/>
<menu_item_call label="Ausziehen" name="Take Off"/>
+ <menu_item_call label="Nur auf mich anwenden" name="Settings Apply Local"/>
+ <menu_item_call label="Auf Parzelle anwenden" name="Settings Apply Parcel"/>
<menu_item_call label="In Marktplatz-Auflistungen kopieren" name="Marketplace Copy"/>
<menu_item_call label="In Marktplatz-Auflistungen verschieben" name="Marketplace Move"/>
<menu_item_call label="--keine Optionen--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/de/menu_inventory_add.xml b/indra/newview/skins/default/xui/de/menu_inventory_add.xml
index af70c08ba1..251b219a12 100644
--- a/indra/newview/skins/default/xui/de/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Sound ([COST] L$)..." name="Upload Sound"/>
<menu_item_call label="Animation ([COST] L$)..." name="Upload Animation"/>
<menu_item_call label="Modell..." name="Upload Model"/>
- <menu_item_call label="Modellassistent..." name="Upload Model Wizard"/>
<menu_item_call label="Mehrfach-Upload ([COST] L$ pro Datei)..." name="Bulk Upload"/>
- <menu_item_call label="Hochlade-Berechtigungen (Standard) festlegen" name="perm prefs"/>
</menu>
<menu_item_call label="Neuer Ordner" name="New Folder"/>
<menu_item_call label="Neues Skript" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Neue Unterhose" name="New Underpants"/>
<menu_item_call label="Neues Alpha" name="New Alpha"/>
<menu_item_call label="Neue Tätowierung" name="New Tattoo"/>
+ <menu_item_call label="Neues Universal" name="New Universal"/>
<menu_item_call label="Neue Physik" name="New Physics"/>
</menu>
<menu label="Neue Körperteile" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Neues Haar" name="New Hair"/>
<menu_item_call label="Neue Augen" name="New Eyes"/>
</menu>
+ <menu label="Neue Einstellungen" name="New Settings">
+ <menu_item_call label="Neuer Himmel" name="New Sky"/>
+ <menu_item_call label="Neues Wasser" name="New Water"/>
+ <menu_item_call label="Neuer Tageszyklus" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
index 211cc5c54e..817ec28cff 100644
--- a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Neues Alpha" name="New Alpha"/>
<menu_item_call label="Neue Physik" name="New Physics"/>
<menu_item_call label="Neue Tätowierung" name="New Tattoo"/>
+ <menu_item_call label="Neues Universal" name="New Universal"/>
</menu>
<menu label="Neue Körperteile" name="New Body Parts">
<menu_item_call label="Neue Form" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/de/menu_save_settings.xml b/indra/newview/skins/default/xui/de/menu_save_settings.xml
new file mode 100644
index 0000000000..458c3fdc14
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Speichern" name="save_settings"/>
+ <menu_item_check label="Speichern unter" name="save_as_new_settings"/>
+ <menu_item_check label="Festlegen" name="commit_changes"/>
+ <menu_item_check label="Nur auf mich anwenden" name="apply_local"/>
+ <menu_item_check label="Auf Parzelle anwenden" name="apply_parcel"/>
+ <menu_item_check label="Auf Region anwenden" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_settings_add.xml b/indra/newview/skins/default/xui/de/menu_settings_add.xml
new file mode 100644
index 0000000000..ebf6c2b314
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Neuer Himmel" name="New Sky"/>
+ <menu_item_call label="Neues Wasser" name="New Water"/>
+ <menu_item_call label="Neuer Tageszyklus" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_settings_gear.xml b/indra/newview/skins/default/xui/de/menu_settings_gear.xml
new file mode 100644
index 0000000000..4be4675899
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Bearbeiten" name="edit_settings"/>
+ <menu_item_call label="Nur auf mich anwenden" name="Settings Apply Local"/>
+ <menu_item_call label="Auf Parzelle anwenden" name="Settings Apply Parcel"/>
+ <menu_item_call label="Auf Region anwenden" name="Settings Apply Region"/>
+ <menu_item_call label="Kopieren" name="copy_settings"/>
+ <menu_item_call label="Einfügen" name="paste_settings"/>
+ <menu_item_call label="UUID kopieren" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index 5917a0b529..6ea4ae9ab3 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="Parzelleneigenschaften" name="Parcel Properties"/>
<menu_item_check label="Menü „Erweitert“" name="Show Advanced Menu"/>
</menu>
- <menu label="Sonne" name="Sun">
+ <menu label="Umgebung" name="Environment">
<menu_item_check label="Sonnenaufgang" name="Sunrise"/>
<menu_item_check label="Mittag" name="Noon"/>
<menu_item_check label="Sonnenuntergang" name="Sunset"/>
<menu_item_check label="Mitternacht" name="Midnight"/>
- <menu_item_check label="Regionseinstellungen verwenden" name="Use Region Settings"/>
- </menu>
- <menu label="Umwelt-Editor" name="Environment Editor">
- <menu_item_call label="Umwelt-Einstellungen..." name="Environment Settings"/>
- <menu label="Wasser-Voreinstellungen" name="Water Presets">
- <menu_item_call label="Neue Voreinstellung..." name="new_water_preset"/>
- <menu_item_call label="Voreinstellung bearbeiten..." name="edit_water_preset"/>
- <menu_item_call label="Voreinstellung löschen..." name="delete_water_preset"/>
- </menu>
- <menu label="Himmel-Voreinstellungen" name="Sky Presets">
- <menu_item_call label="Neue Voreinstellung..." name="new_sky_preset"/>
- <menu_item_call label="Voreinstellung bearbeiten..." name="edit_sky_preset"/>
- <menu_item_call label="Voreinstellung löschen..." name="delete_sky_preset"/>
- </menu>
- <menu label="Tag-Voreinstellungen" name="Day Presets">
- <menu_item_call label="Neue Voreinstellung..." name="new_day_preset"/>
- <menu_item_call label="Voreinstellung bearbeiten..." name="edit_day_preset"/>
- <menu_item_call label="Voreinstellung löschen..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Gemeinsame Umgebung verwenden" name="Use Shared Environment"/>
+ <menu_item_call label="Meine Umgebungen..." name="my_environs"/>
+ <menu_item_call label="Persönliche Beleuchtung..." name="adjustment_tool"/>
+ <menu_item_check label="Wolken pausieren" name="pause_clouds"/>
</menu>
</menu>
<menu label="Bauen" name="BuildTools">
@@ -346,6 +331,9 @@
<menu_item_check label="Automatische Alpha-Masken (nicht aufgeschoben)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Animationstexturen" name="Animation Textures"/>
<menu_item_check label="Texturen deaktivieren" name="Disable Textures"/>
+ <menu_item_check label="Umgebung deaktivieren" name="Disable Ambient"/>
+ <menu_item_check label="Sonnenlicht deaktivieren" name="Disable Sunlight"/>
+ <menu_item_check label="Lokale Lichtquellen deaktivieren" name="Disable Local Lights"/>
<menu_item_check label="Voll-Res-Texturen" name="Rull Res Textures"/>
<menu_item_check label="Angehängte Lichter rendern" name="Render Attached Lights"/>
<menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/>
@@ -477,6 +465,7 @@
<menu_item_call label="Rock" name="Skirt"/>
<menu_item_call label="Alpha" name="Alpha"/>
<menu_item_call label="Tätowierung" name="Tattoo"/>
+ <menu_item_call label="Universal" name="Universal"/>
<menu_item_call label="Physik" name="Physics"/>
<menu_item_call label="Alle Kleider" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
index 283e454a06..e4c2c88f11 100644
--- a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Ersetzen" name="wear_replace"/>
<menu_item_call label="Anziehen" name="wear_wear"/>
<menu_item_call label="Hinzufügen" name="wear_add"/>
+ <menu_item_call label="Berühren" name="touch" />
<menu_item_call label="Ausziehen / Abnehmen" name="take_off_or_detach"/>
<menu_item_call label="Abnehmen" name="detach"/>
<context_menu label="Anhängen an" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
index dacf898b6a..6cb0d095e7 100644
--- a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Outfit bearbeiten" name="edit"/>
+ <menu_item_call label="Berühren" name="touch"/>
+ <menu_item_call label="Bearbeiten" name="edit_item"/>
+ <menu_item_call label="Outfit bearbeiten" name="edit_outfit"/>
<menu_item_call label="Ausziehen" name="takeoff"/>
<menu_item_call label="Outfitliste in Zwischenablage kopieren" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
index 61002b3dad..c729ef6b00 100644
--- a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Berühren" name="touch_attach"/>
<menu_item_call label="Ausziehen" name="take_off"/>
<menu_item_call label="Abnehmen" name="detach"/>
- <menu_item_call label="Outfit bearbeiten" name="edit"/>
+ <menu_item_call label="Outfit bearbeiten" name="edit_outfit"/>
<menu_item_call label="Bearbeiten" name="edit_item"/>
<menu_item_call label="Original anzeigen" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index feb1ae23a5..359a835630 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -266,6 +266,10 @@ Möchten Sie den ausgewählten Einwohnern Änderungsrechte gewähren?
Möchten Sie den ausgewählten Einwohnern die Änderungsrechte entziehen?
<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ Ein Gruppenname muss zwischen [MIN_LEN] und [MAX_LEN] Zeichen lang sein.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
Gruppe konnte nicht erstellt werden.
[MESSAGE]
@@ -366,7 +370,7 @@ Fortfahren?
Sie haben nicht genug L$, um dieser Gruppe beizutreten.
</notification>
<notification name="CreateGroupCost">
- Die Gründung dieser Gruppe kostet 100 L$.
+ Die Erstellung dieser Gruppe kostet L$[COST].
Gruppen müssen mehr als ein Mitglied haben oder sie werden gelöscht.
Bitte laden Sie innerhalb von 48 Stunden Mitglieder in Ihre Gruppe ein.
<usetemplate canceltext="Abbrechen" name="okcancelbuttons" notext="Abbrechen" yestext="Gruppe für 100 L$ erstellen"/>
@@ -508,6 +512,9 @@ Um Medien nur auf einer Fläche einzufügen, wählen Sie „Oberfläche auswähl
<notification name="ErrorEncodingSnapshot">
Fehler beim Erstellen des Fotos!
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Du brauchst L$[COST], um diesen Artikel hochzuladen.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Es kostet L$[COST], um ein Foto in Ihrem Inventar zu speichern. Sie können entweder L$ kaufen oder das Foto auf Ihrem Computer speichern.
</notification>
@@ -1753,11 +1760,14 @@ Diese Gruppe verlassen?
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- Die Gruppenbegrenzung für Basiskonten ist [MAX_BASIC]; für
-[https://secondlife.com/premium/ Premium-]Konten ist sie [MAX_PREMIUM].
-Wenn Sie ein Downgrade Ihres Kontos durchgeführt haben, müssen Sie das Gruppenlimit unter [MAX_BASIC] bringen, bevor sich weitere Personen registrieren können.
-
-[https://secondlife.com/my/account/membership.php Noch heute upgraden!]
+ Einwohner mit Basic-Mitgliedschaft können bis zu [MAX_BASIC] Gruppen beitreten.
+Premium-Mitgliedschaften erlauben bis zu [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Mehr Informationen oder Upgrade]
+ <usetemplate name="okbutton" yestext="Schließen"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ Einwohner mit Basic-Mitgliedschaft können bis zu [MAX_BASIC] Gruppen beitreten.
+Premium-Mitgliedschaften erlauben bis zu [MAX_PREMIUM]. Premium-Plus-Mitgliedschaften
+erlauben bis zu [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Mehr Informationen oder Upgrade]
<usetemplate name="okbutton" yestext="Schließen"/>
</notification>
<notification name="KickUser">
@@ -1976,6 +1986,11 @@ Tausende Regionen werden verändert und der Spaceserver wird dadurch stark belas
Durch Deaktivieren dieser Option können Einstellungen der Parzellenbesitzer zum Schutz vor Belästigungen, zur Aufrechterhaltung der Privatsphäre oder zum Schutz von Minderjährigen vor nicht altersgemäßen Inhalten aufgehoben werden. Bitte sprechen Sie mit den Parzellenbesitzern, falls erforderlich.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Durch Deaktivieren dieser Option werden jegliche benutzerdefinierten Umgebungen entfernt, die von den Parzelleneigentümern zu ihren Parzellen hinzugefügt wurden. Bitte sprechen Sie mit den Parzellenbesitzern, falls erforderlich.
+Fortfahren?
+ <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
<usetemplate name="okbutton" yestext="OK"/>
@@ -2455,7 +2470,15 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies
Diese Tageszyklusdatei verweist auf eine fehlende Himmel-Datei: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- Die Einstellungen konnten nicht auf die Region angewendet werden. Verlassen Sie die Region und kehren Sie zurück, um das Problem zu beheben. Angegebener Grund: [FAIL_REASON]
+ Die Einstellungen konnten nicht auf die Region angewendet werden. Grund: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Eine lokale Textur wird im Pfad [TRACK], Frame #[FRAMENO] ([FRAME]%) im Feld [FIELD] verwendet.
+Die Einstellungen können nicht mit lokalen Texturen gespeichert werden.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Im Feld [FIELD] wird eine lokale Textur verwendet.
+Die Einstellungen können nicht mit lokalen Texturen gespeichert werden.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Der letzte Schlüssel in diesem Tageszyklus kann nicht gelöscht werden, da ein Tageszyklus nicht leer sein kann. Statt den letzten verbleibenden Schlüssel zu löschen, versuchen Sie stattdessen, ihn zu modifizieren und dann einen neuen zu erstellen.
@@ -3307,6 +3330,22 @@ Diese werden für ein paar Sekunden sicherheitshalber gesperrt.
Sie wurden vom Moderator stummgeschaltet.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Leider konnten wir für diese Sitzung keine Informationen zu den Leistungen erhalten. Dies sollte in einer normalen Produktionsumgebung nicht passieren. Kontaktiere bitte den Support. Diese Sitzung wird nicht normal laufen, und wir empfehlen, die Sitzung neu zu starten.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Dadurch werden [COUNT] Artikel zu einem Gesamtpreis von L$[COST] hochgeladen. Möchtest du mit dem Hochladen fortfahren?
+ <usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Hochladen"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Ausgewählte Dateien können nicht per Bulk-Upload hochgeladen werden.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Einige der ausgewählten Dateien können nicht per Bulk-Upload hochgeladen werden.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
Das Hochladen kostet [PRICE] L$. Möchten Sie fortfahren?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Hochladen"/>
@@ -4404,4 +4443,76 @@ Wählen Sie eine kleinere Landfläche aus.
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ Die Einstellungen für [NAME] konnten nicht aus der Datenbank geladen werden.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Diese Einstellungen können nicht auf die Umgebung angewendet werden.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Diese Einstellungen können nicht auf die Umgebung angewendet werden.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Diese Region unterstützt keine Umgebungseinstellungen.
+ </notification>
+ <notification label="Outfit speichern" name="SaveSettingAs">
+ Aktuelle Umgebungseinstellungen speichern unter:
+ <form name="form">
+ <input name="message">
+ [DESC] (neu)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Abbrechen"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Alte Windlight-Einstellungen [NAME] konnten nicht aus
+[FILE] geladen werden.
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Die Umgebung für diese Parzelle kann nicht eingestellt werden.
+Bitte eine Parzelle eingeben oder auswählen, für die Sie die Änderungsrechte besitzen.
+ </notification>
+ <notification name="SettingsUnsuported">
+ Einstellungen werden von dieser Region nicht unterstützt.
+Bitte wechseln sie zu einer Region mit aktivierten Einstellungsmöglichkeiten und versuchen Sie es erneut.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Sie werden die Änderungen an diesem [TYPE] mit der Bezeichnung &quot;[NAME]&quot; verlieren.
+Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate ignoretext="Sind Sie sicher, dass Sie die Änderungen verlieren möchten?" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Sie sind dabei, alle angewendeten Einstellungen zu entfernen.
+Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Sie sind dabei, alle angewendeten persönlichen Beleuchtungseinstellungen zu entfernen.
+Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Sie versuchen, nicht transferierbare Einstellungen in diesen Tageszyklus zu importieren. Wenn Sie fortfahren, verlieren die von Ihnen bearbeiteten Einstellungen ebenfalls ihre Transferierbarkeit.
+
+Diese Änderung kann nicht rückgängig gemacht werden.
+
+Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate ignoretext="Sind Sie sicher, dass Sie die Transferierbarkeit der Einstellungen aufgeben möchten?" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Sie können Einstellungen aus der Bibliothek nicht direkt bearbeiten.
+Bitte kopieren Sie diese in Ihr Inventar und versuchen Sie es erneut.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Bei diesen Einstellungen wurde ein Problem festgestellt. Sie können momentan nicht gespeichert oder angewendet werden.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Pfad konnte nicht in [TRACK] geladen werden.
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Der Pfad konnte nicht aus [TRACK1] in [TRACK2] geladen werden.
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
index 075a9d752a..a74d16e50a 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Kopftattoo" name="Head Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
- <texture_picker label="Obere Tattoos" name="Upper Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
- <texture_picker label="Untere Tattoos" name="Lower Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
- <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Kopf-Tattoo" name="Head Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Oberes Tattoo" name="Upper Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Unteres Tattoo" name="Lower Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_universal.xml b/indra/newview/skins/default/xui/de/panel_edit_universal.xml
new file mode 100644
index 0000000000..5ae4021b8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Kopf-Tattoo" name="Head Universal Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Oberes Tattoo" name="Upper Universal Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Unteres Tattoo" name="Lower Universal Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Rock-Tattoo" name="Skirt Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Haar-Tattoo" name="Hair Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Augen-Tattoo" name="Eyes Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Tattoo linker Arm" name="Left Arm Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Tattoo linkes Bein" name="Left Leg Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Aux1-Tattoo" name="Aux1 Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Aux2-Tattoo" name="Aux2 Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <texture_picker label="Aux3-Tattoo" name="Aux3 Tattoo" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
index 94a79a0bbd..83593e553f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Tätowierung bearbeiten
</string>
+ <string name="edit_universal_title">
+ Universal bearbeiten
+ </string>
<string name="edit_physics_title">
Physik bearbeiten
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Tätowierung:
</string>
+ <string name="universal_desc_text">
+ Universal:
+ </string>
<string name="physics_desc_text">
Physik:
</string>
diff --git a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
deleted file mode 100644
index 4006022ffc..0000000000
--- a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Legen Sie Artikel hier ab, um sie zum Verkauf in Ihrem Laden vorzubereiten"/>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 1eb3d4d1b9..81de679429 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -18,7 +18,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<string name="no_groups_msg" value="Suchen Sie nach Gruppen? Versuchen Sie es mit der [secondlife:///app/search/groups Suche]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Doppelklicken, um Karte zu öffnen; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Doppelklicken, um zu teleportieren; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
- <string name="GroupCountWithInfo" value="Sie gehören [COUNT] Gruppen an und können [REMAINING] weiteren beitreten. [secondlife:/// Möchten Sie noch mehr?]"/>
+ <string name="GroupCountWithInfo" value="Du gehörst zu [COUNT] Gruppen, und kannst [REMAINING] weiteren beitreten. [secondlife:/// Erhöhe dein Limit]"/>
<tab_container name="tabs">
<panel label="IN DER NÄHE" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<dnd_button name="minus_btn" tool_tip="Ausgewählte Gruppe verlassen"/>
</panel>
<text name="groupcount">
- Sie gehören [COUNT] Gruppen an und können [REMAINING] weiteren beitreten.
+ Du gehörst zu [COUNT] Gruppen, und kannst [REMAINING] weiteren beitreten.
</text>
</panel>
<panel label="AKTUELL" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 550a99fe0a..51c82c97f8 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Mittel" name="Medium" value="1"/>
<item label="Groß" name="Large" value="2"/>
</combo_box>
- <check_box label="Blasen-Chat" name="bubble_text_chat"/>
+ <check_box label="Blasen-Chat" name="bubble_text_chat" left_delta="8"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index ff0a6614bd..16fdb69509 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -3,10 +3,10 @@
<text name="preset_text">
(Keine)
</text>
- <text name="QualitySpeed">
+ <text name="QualitySpeed" top_delta="20">
Qualität und Geschwindigkeit:
</text>
- <text name="ShadersPrefText">
+ <text name="ShadersPrefText" top_delta="15">
Niedrig
</text>
<text name="ShadersPrefText2">
@@ -32,10 +32,10 @@
</text>
<check_box initial_value="true" label="Freunde immer darstellen" name="AlwaysRenderFriends"/>
<button label="Ausnahmen..." name="RenderExceptionsButton"/>
- <button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/>
- <button label="Voreinstellung laden..." name="PrefLoadButton"/>
+ <button label="Einstellungen als Voreinstellung speichern" name="PrefSaveButton" width="235" left="5"/>
+ <button label="Voreinstellung laden" name="PrefLoadButton" width="120"/>
min_val=&quot;0.125&quot;
- <button label="Voreinstellung löschen..." name="PrefDeleteButton"/>
- <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/>
+ <button label="Voreinstellung löschen" name="PrefDeleteButton" width="130"/>
+ <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults" width="248"/>
<button label="Erweiterte Einstellungen..." name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
index 1435b7f87d..a8509cabac 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
<text name="Proxy Settings:">
Proxy-Einstellungen:
</text>
- <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy"/>
+ <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy" width="160"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_region_environment.xml b/indra/newview/skins/default/xui/de/panel_region_environment.xml
index 089a3ae5fc..f5e249b083 100644
--- a/indra/newview/skins/default/xui/de/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Umgebung" name="panel_env_info">
- <text name="water_settings_title">
- Wählen Sie die Wasser- und Himmel-/Tageszykluseinstellungen aus, die alle Besucher Ihrer Region sehen sollen. Mehr Infos
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Second Life-Standard verwenden" name="use_sl_default_settings"/>
- <radio_item label="Folgende Einstellungen verwenden" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Wassereinstellung
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Voreinstellung auswählen-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Himmel/Tageszyklus
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Fester Himmel" name="my_sky_settings"/>
- <radio_item label="Tageszyklus" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Voreinstellung auswählen-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Voreinstellung auswählen-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Anwenden" name="apply_btn"/>
- <button label="Abbrechen" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Standardeinstellungen verwenden
+ </string>
+ <string name="str_label_use_region">
+ Regionseinstellungen verwenden
+ </string>
+ <string name="str_altitude_desription">
+ Himmel [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ Es ist keine Parzelle ausgewählt. Umgebungseinstellungen sind deaktiviert.
+ </string>
+ <string name="str_cross_region">
+ Umgebungseinstellungen sind außerhalb der Regionsgrenzen nicht verfügbar.
+ </string>
+ <string name="str_legacy">
+ Umgebungseinstellungen sind für diese Region nicht verfügbar
+ </string>
+ <string name="str_disallowed">
+ Der Grundbesitzverwalter lässt keine Änderung der Parzellenumgebungen in dieser Region zu.
+ </string>
+ <string name="str_too_small">
+ Die Parzellengröße muss mindestens 128 Quadratmeter betragen, um eine Umgebung zu unterstützen.
+ </string>
+ <string name="str_empty">
+ (leer)
+ </string>
+ <string name="str_region_env">
+ (Regionsumgebung)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Inventar verwenden" name="btn_select_inventory"/>
+ <button label="Anpassen" name="btn_edit"/>
+ <check_box label="Parzelleneigentümer können die Umgebung außer Kraft setzen" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Himmel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Unbekannt
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Ziehen Sie eine Einstellung aus dem Inventar auf dieses Zielfeld, um sie als aktuellen Himmel auszuwählen."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Himmel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Unbekannt
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Ziehen Sie eine Einstellung aus dem Inventar auf dieses Zielfeld, um sie als aktuellen Himmel auszuwählen."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Himmel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Unbekannt
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Ziehen Sie eine Einstellung aus dem Inventar auf dieses Zielfeld, um sie als aktuellen Himmel auszuwählen."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Boden
+ </text>
+ <line_editor name="edt_invname_ground">
+ Unbekannt
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Ziehen Sie eine Einstellung aus dem Inventar auf dieses Zielfeld, um sie als aktuellen Himmel auf Bodenhöhe auszuwählen."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Wasser
+ </text>
+ <line_editor name="edt_invname_water">
+ Unbekannt
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Ziehen Sie eine Einstellung aus dem Inventar auf dieses Zielfeld, um sie als aktuelles Wasser auszuwählen."/>
+ </panel>
+ <button label="Zurücksetzen" name="btn_rst_altitudes" tool_tip="Auf Standardhöhen zurücksetzen"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/de/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..f14e3fe47f
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmosphäre und Beleuchtung" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/de/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/de/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..9d78728eed
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Wolken" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/de/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..d7ee6308d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Dichte" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Rayleigh-Exponentialterm:" name="rayleigh_exponential"/>
+ <slider label="Rayleigh-Exponentialskala:" name="rayleigh_exponential_scale"/>
+ <slider label="Rayleigh-Linearterm:" name="rayleigh_linear"/>
+ <slider label="Rayleigh-Konstantenterm:" name="rayleigh_constant"/>
+ <slider label="Rayleigh-Maximalhöhe:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Mie-Exponentialterm:" name="mie_exponential"/>
+ <slider label="Mie-Exponentialskala:" name="mie_exponential_scale"/>
+ <slider label="Mie-Linearterm:" name="mie_linear"/>
+ <slider label="Mie-Konstantenterm:" name="mie_constant"/>
+ <slider label="Mie-Anisofaktor." name="mie_aniso_factor"/>
+ <slider label="Mie-Maximalhöhe:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Absorptions-Exponentialterm:" name="absorption_exponential"/>
+ <slider label="Absorptions-Exponentialskala:" name="absorption_exponential_scale"/>
+ <slider label="Absorptions-Linearterm:" name="absorption_linear"/>
+ <slider label="Absorptions-Konstantenterm:" name="absorption_constant"/>
+ <slider label="Absorptions-Maximalhöhe:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/de/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..9234e22d63
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Sonne und Mond" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Beacon anzeigen" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Beacon anzeigen" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_settings_water.xml b/indra/newview/skins/default/xui/de/panel_settings_water.xml
new file mode 100644
index 0000000000..f11f50dcce
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Wasser" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Fresnel-Versatz:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_tools_texture.xml b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
index e0505ce128..9557f2d6d8 100644
--- a/indra/newview/skins/default/xui/de/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Textur" name="Texture">
- <panel.string name="string repeats per meter">
- Wiederholungen pro Meter
- </panel.string>
- <panel.string name="string repeats per face">
- Wiederholungen pro Fläche
- </panel.string>
<text name="color label">
Farbe
</text>
@@ -114,4 +108,5 @@
<spinner label="Horizontaler Versatz" name="shinyOffsetU"/>
<spinner label="Vertikaler Versatz" name="shinyOffsetV"/>
<check_box initial_value="false" label="Planare Flächen ausrichten" name="checkbox planar align" tool_tip="Texturen auf allen ausgewählten Flächen an der zuletzt ausgewählten Fläche ausrichten. Erfordert planares Texture Mapping."/>
+ <button label="Ausrichten" label_selected="Aktuelle Texturebenen ausrichten" name="button align textures" tool_tip="Aktuelle Texturebenen ausrichten"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/role_actions.xml b/indra/newview/skins/default/xui/de/role_actions.xml
index 26187678a0..5507fcc04d 100644
--- a/indra/newview/skins/default/xui/de/role_actions.xml
+++ b/indra/newview/skins/default/xui/de/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Musik- und Medieneinstellungen ändern" longdescription="Die Einstellungen für Streaming-Musik und Filme finden Sie unter „Land-Info“ &gt; „Medien“." name="land change media" value="20"/>
<action description="„Terrain bearbeiten“ ein/aus" longdescription="„Terrain bearbeiten“ ein/aus. *WARNUNG* „Land-Info“ &gt; „Optionen“ &gt; „Terrain bearbeiten“ ermöglicht jedem das Terraformen Ihres Grundbesitzes und das Setzen und Verschieben von Linden-Pflanzen. Überlegen Sie sich, wem Sie diese Fähigkeit verleihen. Diese Einstellung finden Sie unter „Land-Info“ &gt; „Optionen“." name="land edit" value="21"/>
<action description="„Land-Info“-Optionen einstellen" longdescription="„Sicher (kein Schaden)“ und „Fliegen“ ein- und ausschalten und Einwohnern folgende Aktionen erlauben: „Terrain bearbeiten“, „Bauen“, „Landmarken erstellen“ und „Skripts ausführen“ auf gruppeneigenem Land in „Land-Info“ &gt; Registerkarte „Optionen“." name="land options" value="22"/>
+ <action description="Ändern Sie die Umgebungseinstellungen und den Tageszyklus." longdescription="Ändern Sie die Umgebungseinstellungen im Reiter &quot;Landinformationen -&gt; Umgebung&quot;." name="land change environment" value="46"/>
</action_set>
<action_set description="Diese Fähigkeiten ermöglichen es, Mitgliedern das Umgehen von Restriktionen auf gruppeneigenen Parzellen zu erlauben." name="Parcel Powers">
<action description="„Terrain bearbeiten“ zulassen" longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können auf einer gruppeneigenen Parzelle das Terrain bearbeiten, selbst wenn diese Option unter „Land-Info“ &gt; „Optionen“ deaktiviert ist." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 0fa4ec9aff..43327c132d 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -638,6 +638,15 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="BUTTON_HELP">
Hilfe anzeigen
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Objekte dieses Typs können nicht an Notizkarten
+für diese Region angehängt werden.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ An Notizkarten können nur Objekte ohne
+Berechtigungseinschränkungen für den
+nächsten Eigentümer angehängt werden.
+ </string>
<string name="Searching">
Suchen...
</string>
@@ -717,6 +726,18 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
Fehler bei der Upload-Anforderung. Um das Problem zu lösen,
besuchen Sie bitte http://secondlife.com/support
</string>
+ <string name="SettingValidationError">
+ Validierung für das Importieren der Einstellungen [NAME] fehlgeschlagen
+ </string>
+ <string name="SettingImportFileError">
+ [FILE] konnte nicht geöffnet werden
+ </string>
+ <string name="SettingParseFileError">
+ [FILE] konnte nicht geöffnet werden
+ </string>
+ <string name="SettingTranslateError">
+ Altes Windlight [NAME] konnte nicht übernommen werden
+ </string>
<string name="texture">
Textur
</string>
@@ -792,6 +813,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="symbolic folder link">
Link zu Ordner
</string>
+ <string name="settings blob">
+ Einstellungen
+ </string>
<string name="mesh">
mesh
</string>
@@ -1122,6 +1146,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="ForceSitAvatar">
Ihren Avatar zwingen, sich zu setzen
</string>
+ <string name="ChangeEnvSettings">
+ Umgebungseinstellungen ändern
+ </string>
<string name="NotConnected">
Nicht verbunden
</string>
@@ -1273,6 +1300,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="tattoo">
Tätowierung
</string>
+ <string name="universal">
+ Universal
+ </string>
<string name="physics">
Physik
</string>
@@ -1315,6 +1345,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="tattoo_not_worn">
Tätowierung nicht getragen
</string>
+ <string name="universal_not_worn">
+ Universal nicht getragen
+ </string>
<string name="physics_not_worn">
Physik nicht getragen
</string>
@@ -1366,6 +1399,9 @@ besuchen Sie bitte http://secondlife.com/support
<string name="create_new_tattoo">
Neue Tätowierung erstellen
</string>
+ <string name="create_new_universal">
+ Neues Universal erstellen
+ </string>
<string name="create_new_physics">
Neue Physik erstellen
</string>
@@ -1609,11 +1645,14 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="MarketplaceUpdating">
Aktualisierung läuft...
</string>
+ <string name="UploadFeeInfo">
+ Die Gebühr richtet sich nach deiner Abonnementstufe. Bei höheren Stufen werden niedrigere Gebühren erhoben. [https://secondlife.com/my/account/membership.php? Mehr erfahren]
+ </string>
<string name="Open landmarks">
- Landmarken öffnen
+ Wegweiser öffnen
</string>
<string name="Unconstrained">
- Variabel
+ Unbegrenzt
</string>
<string name="no_transfer" value=" (kein Transferieren)"/>
<string name="no_modify" value=" (kein Bearbeiten)"/>
@@ -2513,6 +2552,27 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="RegionSettings">
Regionseinstellungen
</string>
+ <string name="NoEnvironmentSettings">
+ Diese Region unterstützt keine Umgebungseinstellungen.
+ </string>
+ <string name="EnvironmentSun">
+ Sonne
+ </string>
+ <string name="EnvironmentMoon">
+ Mond
+ </string>
+ <string name="EnvironmentBloom">
+ Bloom
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Wolkenrauschen
+ </string>
+ <string name="EnvironmentNormalMap">
+ Normal-Map
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparent
+ </string>
<string name="ClassifiedClicksTxt">
Klicks: [TELEPORT] teleportieren, [MAP] Karte, [PROFILE] Profil
</string>
@@ -4729,6 +4789,9 @@ Missbrauchsbericht
<string name="New Tattoo">
Neue Tätowierung
</string>
+ <string name="New Universal">
+ Neues Universal
+ </string>
<string name="New Physics">
Neue Physik
</string>
@@ -4855,6 +4918,15 @@ Missbrauchsbericht
<string name="Female - Wow">
Weiblich - Wow
</string>
+ <string name="New Daycycle">
+ Neuer Tageszyklus
+ </string>
+ <string name="New Water">
+ Neues Wasser
+ </string>
+ <string name="New Sky">
+ Neuer Himmel
+ </string>
<string name="/bow">
/verbeugen
</string>
@@ -5027,6 +5099,15 @@ Bitte überprüfen Sie http://status.secondlifegrid.net, um herauszufinden, ob e
<string name="Chat" value=" Chat:">
Chat
</string>
+ <string name="BaseMembership">
+ Basis
+ </string>
+ <string name="PremiumMembership">
+ Premium
+ </string>
+ <string name="Premium PlusMembership">
+ Premium Plus
+ </string>
<string name="DeleteItems">
Ausgewählte Objekte löschen?
</string>
@@ -5383,6 +5464,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="BeaconMedia">
Medien-Beacons werden angezeigt (weiß)
</string>
+ <string name="BeaconSun">
+ Sonnenrichtungs-Beacon ansehen (orange)
+ </string>
+ <string name="BeaconMoon">
+ Mondrichtungs-Beacon ansehen (lila)
+ </string>
<string name="ParticleHiding">
Partikel werden ausgeblendet
</string>
@@ -5410,6 +5497,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Command_Destinations_Label">
Ziele
</string>
+ <string name="Command_Environments_Label">
+ Meine Umgebungen
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5503,6 +5596,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Command_Destinations_Tooltip">
Ziele von Interesse
</string>
+ <string name="Command_Environments_Tooltip">
+ Meine Umgebungen
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Auf Facebook posten
+ </string>
<string name="Command_Flickr_Tooltip">
Auf Flickr hochladen
</string>
@@ -5698,6 +5797,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="ExperiencePermission12">
automatisch Erlebnisberechtigungen akzeptieren
</string>
+ <string name="ExperiencePermission16">
+ ihren Avatar zwingen, sich zu setzen
+ </string>
+ <string name="ExperiencePermission17">
+ Ändern Ihrer Umgebungseinstellungen
+ </string>
<string name="ExperiencePermissionShortUnknown">
unbekannten Vorgang durchführen: [Permission]
</string>
@@ -5722,6 +5827,12 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="ExperiencePermissionShort12">
Berechtigung
</string>
+ <string name="ExperiencePermissionShort16">
+ Sitzen
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Umgebung
+ </string>
<string name="logging_calls_disabled_log_empty">
Unterhaltungen werden nicht protokolliert. Um ein Protokoll zu starten, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ &gt; „Chat“.
</string>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_camera.xml b/indra/newview/skins/default/xui/en/control_table_contents_camera.xml
new file mode 100644
index 0000000000..24cbb2b885
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_camera.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+ <rows
+ enabled="false"
+ name="camera_actions"
+ value="">
+ <columns
+ type="icontext"
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ label="Camera"
+ name="lst_action"
+ value="Cam_FreeCam_Off" />
+ </rows>
+ <rows
+ name="look_up"
+ value="look_up">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Look Up" />
+ </rows>
+ <rows
+ name="look_down"
+ value="look_down">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Look Down" />
+ </rows>
+ <rows
+ name="move_forward"
+ value="move_forward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Forward" />
+ </rows>
+ <rows
+ name="move_backward"
+ value="move_backward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Backward" />
+ </rows>
+ <rows
+ name="move_forward_fast"
+ value="move_forward_fast">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Forward Fast" />
+ </rows>
+ <rows
+ name="move_backward_fast"
+ value="move_backward_fast">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Backward Fast" />
+ </rows>
+ <rows
+ name="spin_over"
+ value="spin_over">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Spin Over" />
+ </rows>
+ <rows
+ name="spin_under"
+ value="spin_under">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Spin Under" />
+ </rows>
+ <rows
+ name="pan_up"
+ value="pan_up">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan Up" />
+ </rows>
+ <rows
+ name="pan_down"
+ value="pan_down">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan Down" />
+ </rows>
+ <rows
+ name="pan_left"
+ value="pan_left">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan Left" />
+ </rows>
+ <rows
+ name="pan_right"
+ value="pan_right">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan Right" />
+ </rows>
+ <rows
+ name="pan_in"
+ value="pan_in">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan In" />
+ </rows>
+ <rows
+ name="pan_out"
+ value="pan_out">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Pan Out" />
+ </rows>
+ <rows
+ name="spin_around_ccw"
+ value="spin_around_ccw">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around counterclockwise"
+ value="Counterclockwise" />
+ </rows>
+ <rows
+ name="spin_around_cw"
+ value="spin_around_cw">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around clockwise"
+ value="Clockwise" />
+ </rows>
+ <rows
+ name="move_forward_sitting"
+ value="move_forward_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Forward Sitting" />
+ </rows>
+ <rows
+ name="move_backward_sitting"
+ value="move_backward_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Backward Sitting" />
+ </rows>
+ <rows
+ name="spin_over_sitting"
+ value="spin_over_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Spin Over Sitting" />
+ </rows>
+ <rows
+ name="spin_under_sitting"
+ value="spin_under_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Spin Under Sitting" />
+ </rows>
+ <rows
+ name="spin_around_ccw_sitting"
+ value="spin_around_ccw_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around counterclockwise sitting"
+ value="Counterclockwise Sitting" />
+ </rows>
+ <rows
+ name="spin_around_cw_sitting"
+ value="spin_around_cw_sitting">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around clockwise sitting"
+ value="Clockwise Sitting" />
+ </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml b/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml
new file mode 100644
index 0000000000..e707aaf22c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+ <columns
+ relative_width="0.34"
+ label="Action"
+ name="lst_action" />
+ <columns
+ relative_width="0.22"
+ label="Primary Control"
+ name="lst_ctrl1" />
+ <columns
+ relative_width="0.22"
+ label="Alternate 1"
+ name="lst_ctrl2" />
+ <columns
+ relative_width="0.22"
+ label="Alternate 2"
+ name="lst_ctrl3" />
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_editing.xml b/indra/newview/skins/default/xui/en/control_table_contents_editing.xml
new file mode 100644
index 0000000000..2a3314840a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_editing.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+ <rows
+ enabled="false"
+ name="editing_actions"
+ value="">
+ <columns
+ type="icontext"
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ label="Editing"
+ name="lst_action"
+ value="Tool_Dozer" />
+ </rows>
+ <rows
+ name="edit_avatar_spin_ccw"
+ value="edit_avatar_spin_ccw">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around avatar counterclockwise"
+ value="Counterclockwise" />
+ </rows>
+ <rows
+ name="edit_avatar_spin_cw"
+ value="edit_avatar_spin_cw">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin around avatar clockwise"
+ value="Clockwise" />
+ </rows>
+ <rows
+ name="edit_avatar_spin_over"
+ value="edit_avatar_spin_over">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin over avatar"
+ value="Camera Spin Over" />
+ </rows>
+ <rows
+ name="edit_avatar_spin_under"
+ value="edit_avatar_spin_under">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Camera spin under avatar"
+ value="Camera Spin Under" />
+ </rows>
+ <rows
+ name="edit_avatar_move_forward"
+ value="edit_avatar_move_forward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Forward" />
+ </rows>
+ <rows
+ name="edit_avatar_move_backward"
+ value="edit_avatar_move_backward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Camera Backward" />
+ </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
new file mode 100644
index 0000000000..ce5d3556b6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+ <rows
+ enabled="false"
+ name="media_actions"
+ value="">
+ <columns
+ type="icontext"
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ label="Sound and Media"
+ name="lst_action"
+ value="Audio_Press" />
+ </rows>
+ <rows
+ name="toggle_pause_media"
+ value="toggle_pause_media">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Play/Pause Media" />
+ </rows>
+ <rows
+ name="toggle_enable_media"
+ value="toggle_enable_media">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Play/Stop All Media" />
+ </rows>
+ <rows
+ name="voice_follow_key"
+ value="voice_follow_key">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Voice" />
+ </rows>
+ <rows
+ name="toggle_voice"
+ value="toggle_voice">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Toggle Voice" />
+ </rows>
+ <rows
+ name="start_chat"
+ value="start_chat">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Start Chat" />
+ </rows>
+ <rows
+ name="start_gesture"
+ value="start_gesture">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Start Gesture" />
+ </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_movement.xml b/indra/newview/skins/default/xui/en/control_table_contents_movement.xml
new file mode 100644
index 0000000000..b410d2dc1c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_movement.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+ <rows
+ enabled="false"
+ name="move_actions"
+ value="">
+ <columns
+ type="icontext"
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ label="Move Actions"
+ name="lst_action"
+ value="Move_Walk_Off" />
+ </rows>
+ <rows
+ name="walk_to"
+ value="walk_to">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Walk to location mouse cursor points to"
+ value="Walk to" />
+ </rows>
+ <rows
+ name="teleport_to"
+ value="teleport_to">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ tool_tip="Teleport to location mouse cursor points to, but not all locations allow direct teleportation so you might be teleported closer to destination instead"
+ value="Teleport to" />
+ </rows>
+ <rows
+ name="push_forward"
+ value="push_forward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Move Forward" />
+ </rows>
+ <rows
+ name="push_backward"
+ value="push_backward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Move Backward" />
+ </rows>
+ <rows
+ name="turn_left"
+ value="turn_left">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Left" />
+ </rows>
+ <rows
+ name="turn_right"
+ value="turn_right">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Right" />
+ </rows>
+ <rows
+ name="slide_left"
+ value="slide_left">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Strafe left" />
+ </rows>
+ <rows
+ name="slide_right"
+ value="slide_right">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Strafe right" />
+ </rows>
+ <rows
+ name="jump"
+ value="jump">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Jump/Up" />
+ </rows>
+ <rows
+ name="push_down"
+ value="push_down">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Down" />
+ </rows>
+ <rows
+ name="run_forward"
+ value="run_forward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Run Forward" />
+ </rows>
+ <rows
+ name="run_backward"
+ value="run_backward">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Run Backward" />
+ </rows>
+ <rows
+ name="run_left"
+ value="run_left">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Run Left" />
+ </rows>
+ <rows
+ name="run_right"
+ value="run_right">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Run Right" />
+ </rows>
+ <rows
+ name="toggle_run"
+ value="toggle_run">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Toggle Run" />
+ </rows>
+ <rows
+ name="toggle_fly"
+ value="toggle_fly">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Fly/Stop flying" />
+ </rows>
+ <rows
+ name="toggle_sit"
+ value="toggle_sit">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Sit/Stand" />
+ </rows>
+ <rows
+ name="stop_moving"
+ value="stop_moving">
+ <columns
+ column="lst_action"
+ font="SansSerif"
+ halign="left"
+ name="lst_action"
+ value="Stop Moving" />
+ </rows>
+</contents>
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 9f853fd960..b2d9e53039 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -123,8 +123,8 @@
No parcel selected.
</panel.string>
<panel.string name="time_stamp_template">
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
- </panel.string>
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
+ </panel.string>
<text
type="string"
length="1"
@@ -1800,7 +1800,7 @@ Only large parcels can be listed in search.
Music URL:
</text>
<line_editor
- follows="left|top"
+ follows="left|top|right"
height="23"
layout="topleft"
left="100"
@@ -2140,5 +2140,17 @@ Only large parcels can be listed in search.
class="land_experiences_panel"
filename="panel_region_experiences.xml">
</panel>
+ <panel
+ border="true"
+ follows="all"
+ label="ENVIRONMENT"
+ layout="topleft"
+ left="0"
+ top="0"
+ help_topic="land_environment_tab"
+ name="land_environment_panel"
+ class="land_environment_panel"
+ filename="panel_region_environment.xml">
+ </panel>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
new file mode 100644
index 0000000000..1f980564d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="405"
+ width="900"
+ layout="topleft"
+ name="floater_add_payment_method"
+ single_instance="true"
+ show_title="false"
+ legacy_header_height="0"
+ header_height="0"
+ background_visible="false"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_minimize="false"
+ can_close="false">
+ <floater.string
+ name="continue_url">
+ https://secondlife.com/my/lindex/buy.php?associate_for_viewer=1
+ </floater.string>
+ <panel
+ background_opaque="false"
+ bg_alpha_color="AddPaymentPanel"
+ border_visible="false"
+ background_visible="true"
+ label="wrapper_panel"
+ layout="topleft"
+ left="0"
+ name="wrapper_panel"
+ top="0"
+ height="405"
+ width="900"
+ follows="all"
+ translate="false">
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ font="SansSerifLargeBold"
+ text_color="White"
+ layout="topleft"
+ left="0"
+ height="14"
+ top_pad="30"
+ width="900"
+ halign="center"
+ name="title_txt">
+ Add a payment method to buy Linden dollars and enjoy more of Second Life.
+ </text>
+ <button
+ follows="top|left|right"
+ height="24"
+ label="Get started"
+ font="SansSerifMedium"
+ layout="topleft"
+ left="320"
+ name="continue_btn"
+ image_unselected="PushButton_Login"
+ image_pressed="PushButton_Login_Pressed"
+ image_hover_unselected="PushButton_Login_Over"
+ label_color="White"
+ top_pad ="15"
+ width="140"/>
+ <button
+ follows="top|left|right"
+ height="24"
+ label="Later"
+ layout="topleft"
+ left_pad="9"
+ name="close_btn"
+ width="90"/>
+ <icon
+ height="195"
+ width="260"
+ image_name="add_payment_image_left"
+ layout="topleft"
+ left="30"
+ name="image_left"
+ top_pad="30"
+ use_draw_context_alpha="false"/>
+ <icon
+ height="195"
+ width="260"
+ image_name="add_payment_image_center"
+ layout="topleft"
+ left_pad="30"
+ name="image_center"
+ use_draw_context_alpha="false"/>
+ <icon
+ height="195"
+ width="260"
+ image_name="add_payment_image_right"
+ layout="topleft"
+ left_pad="30"
+ name="image_right"
+ use_draw_context_alpha="false"/>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ text_color="White"
+ height="75"
+ width="260"
+ top_pad="15"
+ layout="topleft"
+ word_wrap="true"
+ left="30"
+ name="image_left_desc">
+ Create an avatar you love. Choose from millions of items in stores and the Second Life Marketplace. Your style is here.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ text_color="White"
+ height="75"
+ width="260"
+ layout="topleft"
+ word_wrap="true"
+ left_pad="30"
+ name="image_center_desc">
+ Donate to your favorite performers and hosts. Your support helps them create great experiences.
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ text_color="White"
+ height="75"
+ width="260"
+ layout="topleft"
+ word_wrap="true"
+ left_pad="30"
+ name="image_right_desc">
+ Make the home of your dreams. With millions of items available to purchase, you can make your retreat unique.
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
new file mode 100644
index 0000000000..f4a686bae1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater layout="topleft"
+ name="env_adjust_snapshot"
+ help_topic="day_presets"
+ save_rect="false"
+ title="Personal Lighting"
+ width="845"
+ height="280"
+ min_width="500"
+ min_height="275"
+ single_instance="true"
+ can_resize="false">
+ <layout_stack name="outer_stack"
+ width="845"
+ height="275"
+ follows="all"
+ animate="false"
+ top="0"
+ orientation="vertical">
+ <!-- If I put in a timeline it would go here -->
+ <layout_panel name="env_controls"
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="true"
+ height="150"
+ min_height="0"
+ visible="true">
+ <layout_stack name="settings_stack"
+ width="855"
+ height="150"
+ follows="all"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ visible="true"
+ width="160"
+ height="150">
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="80">Ambient:</text>
+ <color_swatch can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="ambient_light"
+ top_pad="5"
+ width="60"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="80">Blue Horizon:</text>
+ <color_swatch can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="blue_horizon"
+ top_pad="5"
+ width="60"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="80">Blue Density:</text>
+ <color_swatch can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="blue_density"
+ top_pad="5"
+ width="60"/>
+ <button
+ follows="left|top"
+ height="23"
+ label="Reset"
+ tool_tip="Close and reset to Shared Environment"
+ layout="topleft"
+ name="btn_reset"
+ left_delta="-2"
+ top_pad="10"
+ width="100"/>
+ <text follows="right|top"
+ height="10"
+ layout="topleft"
+ right="-12"
+ top="5"
+ width="60">Sun Color:</text>
+ <color_swatch can_apply_immediately="true"
+ follows="left|top"
+ height="10"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="sun_color"
+ top_pad="5"
+ width="60"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="80">Cloud Color:</text>
+ <color_swatch can_apply_immediately="true"
+ follows="left|top"
+ height="10"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="cloud_color"
+ top_pad="5"
+ width="60"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ name="cloud_map_label"
+ width="80">Cloud Image:</text>
+ <texture_picker height="63"
+ layout="topleft"
+ left_delta="0"
+ name="cloud_map"
+ top_pad="5"
+ width="60"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="-13"
+ name="cloud_map_label"
+ width="80">Water Image:</text>
+ <texture_picker height="63"
+ layout="topleft"
+ left_delta="0"
+ name="water_normal_map"
+ top_pad="5"
+ width="60"/>
+ </layout_panel>
+ <layout_panel border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ visible="true"
+ width="200"
+ height="150">
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="5"
+ top_pad="5"
+ width="80">Haze Horizon:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="5"
+ name="haze_horizon"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="80">Haze Density:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="5"
+ name="haze_density"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="185">Cloud Coverage:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="cloud_coverage"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="185">Cloud Scale:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.01"
+ max_val="3"
+ name="cloud_scale"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="15"
+ width="80">Scene Gamma:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ max_val="20"
+ name="scene_gamma"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ height="150"
+ width="310"
+ min_height="0"
+ visible="true">
+ <text follows="top|left"
+ font="SansSerifBold"
+ height="10"
+ layout="topleft"
+ name="label"
+ left="5"
+ top="5"
+ width="105">Sun:</text>
+ <sun_moon_trackball name="sun_rotation"
+ follows="left|top"
+ left_delta="0"
+ top_delta="20"
+ height="150"
+ width="150"
+ thumb_mode="sun"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="200">Azimuth:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="359.99"
+ name="sun_azimuth"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="200">Elevation:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-90"
+ max_val="90"
+ name="sun_elevation"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <check_box control_name="sunbeacon"
+ width="60"
+ height="16"
+ label="Show Beacon"
+ layout="topleft"
+ name="sunbeacon"
+ left_delta="-5"
+ top_pad="8"
+ follows="left|top"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="95"
+ top="25"
+ width="80">Scale:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.25"
+ max_val="20"
+ name="sun_scale"
+ top_delta="15"
+ width="130"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="100">Glow Focus:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-2"
+ max_val="2"
+ name="glow_focus"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="200">Glow Size:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1.99"
+ name="glow_size"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="10"
+ width="200">Star Brightness:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="500"
+ name="star_brightness"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ height="150"
+ width="160"
+ min_height="0"
+ visible="true">
+ <text follows="top|left"
+ font="SansSerifBold"
+ height="10"
+ layout="topleft"
+ name="label"
+ left="5"
+ top="5"
+ width="105">Moon:</text>
+ <sun_moon_trackball name="moon_rotation"
+ follows="left|top"
+ left_delta="0"
+ top_delta="20"
+ height="150"
+ width="150"
+ thumb_mode="moon"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="200">Azimuth:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="359.99"
+ name="moon_azimuth"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="200">Elevation:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-90"
+ max_val="90"
+ name="moon_elevation"
+ top_pad="5"
+ width="130"
+ can_edit_text="true"/>
+ <check_box control_name="moonbeacon"
+ follows="left|top"
+ width="60"
+ height="16"
+ label="Show Beacon"
+ layout="topleft"
+ name="moonbeacon"
+ left_delta="0"
+ top_pad="8"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
index b5538a511c..c4ffba33fd 100644
--- a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="190"
+ height="180"
layout="topleft"
name="Anim Preview"
help_topic="animation_anim_preview"
@@ -60,9 +60,9 @@
height="22"
label="Upload (L$[AMOUNT])"
layout="topleft"
- left="45"
+ left="35"
name="ok_btn"
- top_pad="60"
+ top_pad="15"
width="150" />
<button
follows="right|bottom"
@@ -73,4 +73,17 @@
name="cancel_btn"
left_pad="5"
width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="35"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ skip_link_underline="true"
+ name="info_text"
+ word_wrap="true"
+ top_pad="10"
+ width="270"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
index cb6b2f6ebc..0c62bfe304 100644
--- a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="610"
+ height="645"
layout="topleft"
name="Animation Preview"
help_topic="animation_preview"
@@ -570,4 +570,17 @@ We recommend BVH files exported from Poser 4.
name="cancel_btn"
left="142"
width="128" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="35"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ skip_link_underline="true"
+ name="info_text"
+ word_wrap="true"
+ top_pad="10"
+ width="270"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml
index 92c5d8bcbe..3df2683ca8 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar.xml
@@ -14,7 +14,7 @@
help_topic="avatar"
save_rect="true"
save_visibility="true"
- title="CHOOSE AN AVATAR"
+ title="COMPLETE AVATARS"
width="700">
<web_browser
top="25"
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
index bac3ea86f1..6540f5e348 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
@@ -28,11 +28,13 @@
name="scroll_content_panel"
follows="left|top"
min_height="300"
+ min_width="300"
layout="topleft"
top="0"
background_visible="false"
left="0"
- height="680">
+ height="1165"
+ width="1015">
<text
type="string"
length="1"
@@ -102,6 +104,14 @@ Textures
name="hair_alpha"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Hair Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="hair_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -135,6 +145,14 @@ Textures
name="head_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Head Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="head_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -160,6 +178,14 @@ Textures
name="eyes_alpha"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Eyes Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="eyes_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -225,6 +251,14 @@ Textures
name="upper_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Upper Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="upper_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -298,6 +332,14 @@ Textures
name="lower_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Lower Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="lower_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -315,6 +357,99 @@ Textures
name="skirt"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Skirt Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="skirt_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="Left Arm"
+ layout="topleft"
+ left="10"
+ name="leftarm-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="Left Arm Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="leftarm_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="Left Leg"
+ layout="topleft"
+ left="10"
+ name="leftleg-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="Left Leg Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="leftleg_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 1"
+ layout="topleft"
+ left="10"
+ name="aux1-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 1 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux1_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 2"
+ layout="topleft"
+ left="10"
+ name="aux2-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 2 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux2_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 3"
+ layout="topleft"
+ left="10"
+ name="aux3-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 3 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux3_tattoo"
+ top_delta="0"
+ width="92" />
</panel>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml
index 3d29356b22..d5947fc0af 100644
--- a/indra/newview/skins/default/xui/en/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/en/floater_beacons.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="245"
+ height="310"
layout="topleft"
name="beacons"
help_topic="beacons"
@@ -12,7 +12,7 @@
width="240">
<panel
follows="left|top|right|bottom"
- height="240"
+ height="305"
layout="topleft"
left="10"
name="beacons_panel"
@@ -143,6 +143,43 @@
<check_box.commit_callback
function="Beacons.UICheck" />
</check_box>
+ <view_border
+ bevel_style="in"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="5"
+ width="220"/>
+ <text
+ follows="all"
+ height="16"
+ font="SansSerif"
+ left="0"
+ top_pad="7"
+ name="label_objects"
+ text_color="White"
+ type="string">
+ Show direction to:
+ </text>
+ <check_box
+ control_name="sunbeacon"
+ height="16"
+ label="Sun"
+ layout="topleft"
+ name="sun" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
+ <check_box
+ control_name="moonbeacon"
+ height="16"
+ label="Moon"
+ layout="topleft"
+ name="moon" >
+ <check_box.commit_callback
+ function="Beacons.UICheck" />
+ </check_box>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 9fa93b640f..431c33a339 100644
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -156,7 +156,20 @@
name="icon_texture"
tool_tip="Textures"
left_pad="2" />
-
+ <check_box
+ control_name="BulkChangeIncludeSettings"
+ height="16"
+ name="check_settings"
+ left="245"
+ top="25"
+ width="16" />
+ <icon
+ height="16"
+ image_name="Inv_Settings"
+ mouse_opaque="true"
+ name="icon_setting"
+ tool_tip="Environment settings"
+ left_pad="2" />
<button
height="23"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 553c5d51d0..e8e83301be 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- legacy_header_height="18"
+
can_minimize="false"
- height="275"
+ height="285"
layout="topleft"
title="BUY L$"
name="buy currency"
@@ -13,315 +13,389 @@
name="buy_currency">
Buy L$ [LINDENS] for approx. [LOCALAMOUNT]
</floater.string>
+ <floater.string
+ name="info_cannot_buy">
+ Unable to Buy
+ </floater.string>
+ <floater.string
+ name="estimated_zero">
+ US$ 0.00
+ </floater.string>
<icon
- height="215"
+ height="245"
image_name="Linden_Dollar_Background"
layout="topleft"
left="0"
name="normal_background"
- top="17"
+ top="0"
use_draw_context_alpha="false"
width="350" />
- <text
- type="string"
- length="1"
- follows="top|left|right"
- font="SansSerifHuge"
+ <layout_stack
+ animate="false"
+ name="outer_stack"
+ layout="topleft"
+ follows="all"
+ orientation="vertical"
+ left="0"
+ top="0"
+ width="350"
+ height="285">
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_title"
layout="topleft"
- left="20"
- height="30"
- top="25"
- width="340"
- name="info_need_more">
- You need more L$
- </text>
- <text
- type="string"
- length="1"
- follows="top|left"
- height="16"
+ follows="all"
+ width="350"
+ height="35">
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ font="SansSerifLarge"
+ layout="topleft"
+ left="20"
+ height="30"
+ top="8"
+ width="340"
+ name="info_need_more">
+ You need more L$
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left|right"
+ font="SansSerifLarge"
+ layout="topleft"
+ left="20"
+ height="30"
+ top="8"
+ width="300"
+ name="info_buying">
+ Buy L$
+ </text>
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="20"
+ name="text_border"
+ top_delta="25"
+ width="300"/>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_price"
layout="topleft"
- top="246"
- left="15"
- width="300"
- name="contacting">
- Contacting LindeX...
- </text>
- <text
- type="string"
- length="1"
- follows="top|left"
- font="SansSerifHuge"
+ follows="all"
+ width="350"
+ height="18">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="target_price_label"
+ top_pad="3"
+ width="210">
+ You need
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifMedium"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="target_price"
+ top_delta="0"
+ width="120">
+ L$ [AMT]
+ </text>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_balance"
layout="topleft"
- left="20"
- height="30"
- top="25"
- width="300"
- name="info_buying">
- Buy L$
- </text>
- <text
- type="string"
- length="1"
- follows="top|left"
- font="SansSerifMedium"
- height="16"
- layout="topleft"
- left="20"
- name="balance_label"
- top="65"
- width="210">
- I have
- </text>
- <text
- type="string"
- length="1"
- font="SansSerifMedium"
- follows="top|left"
- halign="right"
- height="16"
- layout="topleft"
- left="200"
- name="balance_amount"
- top_delta="0"
- width="120">
+ follows="all"
+ width="350"
+ height="19">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="balance_label"
+ top_pad="5"
+ width="210">
+ You now have
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifMedium"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="balance_amount"
+ top_delta="0"
+ width="120">
L$ [AMT]
- </text>
- <text
- type="string"
- length="1"
- follows="top|left"
- font="SansSerifMedium"
- height="16"
- top="95"
- layout="topleft"
- left="20"
- name="currency_action"
- width="210">
- I want to buy
- </text>
- <text
- font="SansSerifMedium"
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- top_delta="0"
- left="217"
- name="currency_label"
- width="15">
- L$
- </text>
- <line_editor
- type="string"
- max_length_bytes="10"
- halign="right"
- font="SansSerifMedium"
- select_on_focus="true"
- follows="top|left"
- top_delta="-7"
- height="22"
- label="L$"
- left_pad="3"
- name="currency_amt"
- width="85">
- 1234
- </line_editor>
- <text
- type="string"
- font="SansSerifMedium"
- length="1"
- follows="top|left"
- height="16"
- layout="topleft"
- left="20"
- top="125"
- name="buying_label"
- width="210">
- For the price
- </text>
- <text
- type="string"
- length="1"
- font="SansSerifMedium"
- text_color="EmphasisColor"
- follows="top|left"
- halign="right"
- height="16"
- top_delta="0"
- layout="topleft"
- left="150"
- name="currency_est"
- width="170">
- approx. [LOCALAMOUNT]
- </text>
- <text
- type="string"
- font="SansSerifSmall"
- text_color="EmphasisColor"
- length="1"
- follows="top|left"
- height="16"
+ </text>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_required"
layout="topleft"
- top="125"
- left="170"
- width="150"
- halign="right"
- name="getting_data">
- Estimating...
- </text>
- <text
- type="string"
- font="SansSerifSmall"
- top="145"
- length="1"
- follows="top|left"
- height="16"
- halign="right"
- left="20"
- width="300"
- layout="topleft"
- name="buy_action">
- [ACTION]
- </text>
- <text
- type="string"
- font="SansSerifMedium"
- length="1"
- follows="top|left"
- height="16"
- layout="topleft"
- left="20"
- name="total_label"
- top="165"
- width="210">
- My new balance will be
- </text>
- <text
- type="string"
- length="1"
- font="SansSerifMedium"
- follows="top|left"
- top_delta="0"
- height="16"
- layout="topleft"
- left="200"
- halign="right"
- name="total_amount"
- width="120">
+ follows="all"
+ width="350"
+ height="22">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ font.style="BOLD"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="required_label"
+ top_pad="6"
+ width="210">
+ You should buy at least
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifMedium"
+ follows="top|left"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="200"
+ name="required_amount"
+ top_delta="0"
+ width="120">
L$ [AMT]
- </text>
- <text
- type="string"
- length="1"
- text_color="LtGray_50"
- follows="top|left"
+ </text>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_action"
layout="topleft"
- halign="right"
- top="189"
- left="20"
- width="300"
- height="30"
- name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
- </text>
- <text
- type="string"
- length="1"
- text_color="LtGray_50"
- follows="top|left"
+ follows="all"
+ width="350"
+ height="90">
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="20"
+ name="text_border_2"
+ top_pad="5"
+ width="300"/>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ font="SansSerifMedium"
+ height="16"
+ top_pad="15"
+ layout="topleft"
+ left="20"
+ name="currency_action"
+ width="210">
+ Choose amount to buy
+ </text>
+ <text
+ font="SansSerifMedium"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ top_delta="0"
+ left="247"
+ name="currency_label"
+ width="15">
+ L$
+ </text>
+ <line_editor
+ type="string"
+ max_length_bytes="10"
+ halign="right"
+ font="SansSerifMedium"
+ select_on_focus="true"
+ follows="top|left"
+ top_delta="-4"
+ height="22"
+ label="L$"
+ left_pad="3"
+ name="currency_amt"
+ width="55">
+ 1234
+ </line_editor>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifMedium"
+ text_color="EmphasisColor"
+ follows="top|left"
+ halign="right"
+ height="16"
+ top_pad="4"
+ layout="topleft"
+ left="150"
+ name="currency_est"
+ width="170">
+ Approx. [LOCALAMOUNT]
+ </text>
+ <text
+ type="string"
+ font="SansSerifSmall"
+ text_color="EmphasisColor"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="170"
+ top_delta="0"
+ width="150"
+ halign="right"
+ name="getting_data">
+ Estimating...
+ </text>
+ <text
+ type="string"
+ font="SansSerifMedium"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="20"
+ name="total_label"
+ top_pad="10"
+ width="210">
+ Your new balance will be
+ </text>
+ <text
+ type="string"
+ length="1"
+ font="SansSerifMedium"
+ follows="top|left"
+ top_delta="0"
+ height="16"
+ layout="topleft"
+ left="200"
+ halign="right"
+ name="total_amount"
+ width="120">
+ L$ [AMT]
+ </text>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_msg"
layout="topleft"
- halign="right"
- top="202"
- left="20"
- width="300"
- height="30"
- name="exchange_rate_note">
+ follows="all"
+ width="350"
+ height="50">
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="20"
+ name="text_border_3"
+ top_pad="0"
+ width="300"/>
+ <text
+ type="string"
+ length="1"
+ text_color="LtGray_50"
+ follows="top|left"
+ layout="topleft"
+ halign="right"
+ top_pad="3"
+ left="20"
+ width="300"
+ height="30"
+ name="currency_links">
+ [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
+ </text>
+ <text
+ type="string"
+ length="1"
+ text_color="LtGray_50"
+ follows="top|left"
+ layout="topleft"
+ halign="right"
+ top="19"
+ left="20"
+ width="300"
+ height="30"
+ name="exchange_rate_note">
Re-enter amount to see the latest exchange rate.
- </text>
- <text
- type="string"
- length="1"
- text_color="LtGray_50"
- follows="top|left"
- layout="topleft"
- halign="right"
- top="208"
- left="10"
- width="310"
- height="35"
- name="purchase_warning_repurchase">
- Confirming this purchase only buys L$, not the object.
- </text>
- <text
- type="string"
- length="1"
- text_color="LtGray_50"
- follows="top|left"
- layout="topleft"
- halign="right"
- top="213"
- left="20"
- width="300"
- height="30"
- name="purchase_warning_notenough">
- You aren&apos;t buying enough L$. Please increase the amount.
- </text>
-
- <button
- follows="bottom|left"
- height="20"
- label="Buy Now"
- layout="topleft"
- left="151"
- name="buy_btn"
- top="242"
- width="90"/>
- <button
- follows="bottom|right"
- height="20"
- label="Cancel"
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ layout="topleft"
+ font="SansSerifMedium"
+ top="10"
+ left="20"
+ width="310"
+ height="35"
+ name="purchase_warning_repurchase">
+After you receive your L$, you should try your
+purchase again.
+ </text>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="layout_panel_buttons"
layout="topleft"
- left_pad="10"
- name="cancel_btn"
- width="90"/>
- <icon
- height="215"
- image_name="Linden_Dollar_Alert"
- layout="topleft"
- left="0"
- name="error_background"
- top="15"
- use_draw_context_alpha="false"
- width="350"/>
- <text
- type="string"
- font="SansSerifHuge"
- left="165"
- width="360"
- height="25"
- top="25"
- name="info_cannot_buy">
- Unable to Buy
- </text>
- <text
- type="string"
- width="176"
- height="125"
- top="60"
- left="165"
- word_wrap="true"
- follows="bottom|right"
- name="cannot_buy_message">
- </text>
- <button
- follows="bottom|left"
- height="20"
- label="Continue to the Web"
- layout="topleft"
- left="170"
- name="error_web"
- top="200"
- width="160"/>
+ follows="all"
+ width="350"
+ height="40">
+ <text
+ type="string"
+ length="1"
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ top_pad="0"
+ left="15"
+ width="300"
+ name="contacting">
+ Contacting LindeX...
+ </text>
+ <button
+ follows="top|left|right"
+ height="20"
+ label="Buy L$ now"
+ layout="topleft"
+ left="151"
+ name="buy_btn"
+ bottom_delta ="8"
+ width="90"/>
+ <button
+ follows="top|left|right"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_pad="10"
+ name="cancel_btn"
+ width="90"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 49be4290c7..1f7d52dbf5 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -32,6 +32,10 @@
name="no_transfer_text">
(no transfer)
</floater.string>
+ <floater.string
+ name="mupliple_selected">
+ Mupliple selection
+ </floater.string>
<scroll_list
background_visible="true"
draw_border="false"
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 72a7b5540c..9deb38e3af 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -7,7 +7,7 @@
legacy_header_height="18"
can_minimize="true"
can_close="true"
- height="164"
+ height="135"
layout="topleft"
name="camera_floater"
help_topic="camera_floater"
@@ -16,7 +16,7 @@
title="CAMERA CONTROLS"
chrome="true"
save_rect="true"
- width="228">
+ width="400">
<floater.string
name="rotate_tooltip">
Rotate Camera Around Focus
@@ -33,6 +33,7 @@
name="free_mode_title">
View Object
</floater.string>
+ <string name="inactive_combo_text">Use preset</string>
<panel
border="false"
height="123"
@@ -41,112 +42,18 @@
top="0"
mouse_opaque="false"
name="controls"
- width="226">
- <panel
- follows="all"
- height="102"
- layout="topleft"
- left="8"
- name="preset_views_list"
- top="24"
- width="212"
- visible="false">
- <panel_camera_item
- name="front_view">
- <panel_camera_item.mousedown_callback
- function="CameraPresets.ChangeView"
- parameter="front_view" />
- <panel_camera_item.picture
- image_name="Cam_Preset_Front_Off" />
- <panel_camera_item.selected_picture
- image_name="Cam_Preset_Front_On" />
- <panel_camera_item.text
- name="front_view_text">
- Front View
- </panel_camera_item.text>
- </panel_camera_item>
- <panel_camera_item
- name="group_view"
- top_pad="4">
- <panel_camera_item.mousedown_callback
- function="CameraPresets.ChangeView"
- parameter="group_view" />
- <panel_camera_item.picture
- image_name="Cam_Preset_Side_Off" />
- <panel_camera_item.selected_picture
- image_name="Cam_Preset_Side_On" />
- <panel_camera_item.text
- name="side_view_text">
- Side View
- </panel_camera_item.text>
- </panel_camera_item>
- <panel_camera_item
- name="rear_view"
- layout="topleft"
- top_pad="4">
- <panel_camera_item.mousedown_callback
- function="CameraPresets.ChangeView"
- parameter="rear_view" />
- <panel_camera_item.picture
- image_name="Cam_Preset_Back_Off" />
- <panel_camera_item.selected_picture
- image_name="Cam_Preset_Back_On" />
- <panel_camera_item.text
- name="rear_view_text">
- Rear View
- </panel_camera_item.text>
- </panel_camera_item>
- </panel>
- <panel
- follows="all"
- height="68"
- layout="topleft"
- left="8"
- name="camera_modes_list"
- top="24"
- width="212"
- visible="false">
- <panel_camera_item
- name="object_view">
- <panel_camera_item.mousedown_callback
- function="CameraPresets.ChangeView"
- parameter="object_view" />
- <panel_camera_item.text
- name="object_view_text">
- Object View
- </panel_camera_item.text>
- <panel_camera_item.picture
- image_name="Object_View_Off" />
- <panel_camera_item.selected_picture
- image_name="Object_View_On" />
- </panel_camera_item>
- <panel_camera_item
- name="mouselook_view"
- layout="topleft">
- <panel_camera_item.mousedown_callback
- function="CameraPresets.ChangeView"
- parameter="mouselook_view" />
- <panel_camera_item.text
- name="mouselook_view_text">
- Mouselook View
- </panel_camera_item.text>
- <panel_camera_item.picture
- image_name="MouseLook_View_Off" />
- <panel_camera_item.selected_picture
- image_name="MouseLook_View_On" />
- </panel_camera_item>
- </panel>
+ width="220">
<!--TODO: replace + - images -->
<panel
border="false"
class="camera_zoom_panel"
- height="114"
+ height="123"
layout="topleft"
left="0"
mouse_opaque="false"
name="zoom"
- top="20"
- width="226">
+ top="0"
+ width="220">
<joystick_rotate
follows="top|left"
height="78"
@@ -157,8 +64,8 @@
sound_flags="3"
visible="true"
tool_tip="Orbit camera around focus"
- top="20"
- width="78" />
+ top="25"
+ width="78" />
<button
follows="top|left"
height="18"
@@ -169,7 +76,7 @@
left_pad="14"
name="zoom_plus_btn"
width="18"
- top="18">
+ top="23">
<commit_callback
function="Zoom.plus" />
<mouse_held_callback
@@ -214,56 +121,136 @@
scale_image="false"
sound_flags="3"
tool_tip="Move camera up and down, left and right"
- top="20"
+ top="25"
width="78"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="41"
+ top_pad="9"
+ name="precise_ctrs_label"
+ width="200">
+ Use precise controls
+ </text>
</panel>
</panel>
<panel
- border="false"
- height="42"
+ follows="all"
+ height="102"
layout="topleft"
- left="2"
- top_pad="0"
- name="buttons"
- width="226">
- <button
- height="23"
- label=""
- layout="topleft"
- left="70"
- is_toggle="true"
- image_overlay="Cam_Avatar_Off"
- image_selected="PushButton_Selected_Press"
- name="presets_btn"
- tab_stop="false"
- tool_tip="Preset Views"
- top="13"
- width="25">
- </button>
- <button
- height="23"
- label=""
- layout="topleft"
- left_pad="1"
- is_toggle="true"
- image_overlay="PanOrbit_Off"
- image_selected="PushButton_Selected_Press"
- name="pan_btn"
- tab_stop="false"
- tool_tip="Orbit Zoom Pan"
- width="25">
- </button>
- <button
- height="23"
- label=""
- layout="topleft"
- left_pad="1"
- image_overlay="Cam_FreeCam_Off"
- image_selected="PushButton_Selected_Press"
- name="avatarview_btn"
- tab_stop="false"
- tool_tip="Camera modes"
- width="25">
- </button>
- </panel>
+ left_pad="2"
+ name="buttons_panel"
+ top="22"
+ width="212">
+ <panel_camera_item
+ name="front_view"
+ tool_tip="Front View"
+ width="30">
+ <panel_camera_item.mousedown_callback
+ function="CameraPresets.ChangeView"
+ parameter="Front View" />
+ <panel_camera_item.picture
+ image_name="Cam_Preset_Front_Off" />
+ <panel_camera_item.selected_picture
+ image_name="Cam_Preset_Front_On" />
+ </panel_camera_item>
+ <panel_camera_item
+ name="group_view"
+ tool_tip="Side View"
+ width="30"
+ left_pad="4">
+ <panel_camera_item.mousedown_callback
+ function="CameraPresets.ChangeView"
+ parameter="Side View" />
+ <panel_camera_item.picture
+ image_name="Cam_Preset_Side_Off" />
+ <panel_camera_item.selected_picture
+ image_name="Cam_Preset_Side_On" />
+ </panel_camera_item>
+ <panel_camera_item
+ name="rear_view"
+ tool_tip="Rear View"
+ width="30"
+ left_pad="4">
+ <panel_camera_item.mousedown_callback
+ function="CameraPresets.ChangeView"
+ tool_tip="Rear View"
+ parameter="Rear View" />
+ <panel_camera_item.picture
+ image_name="Cam_Preset_Back_Off" />
+ <panel_camera_item.selected_picture
+ image_name="Cam_Preset_Back_On" />
+ </panel_camera_item>
+ <panel_camera_item
+ name="object_view"
+ tool_tip="Object View"
+ width="30"
+ left_pad="4">
+ <panel_camera_item.mousedown_callback
+ function="CameraPresets.ChangeView"
+ parameter="object_view" />
+ <panel_camera_item.picture
+ image_name="Object_View_Off" />
+ <panel_camera_item.selected_picture
+ image_name="Object_View_On" />
+ </panel_camera_item>
+ <panel_camera_item
+ name="mouselook_view"
+ tool_tip="Mouselook View"
+ width="30"
+ left_pad="4">
+ <panel_camera_item.mousedown_callback
+ function="CameraPresets.ChangeView"
+ parameter="mouselook_view" />
+ <panel_camera_item.picture
+ image_name="MouseLook_View_Off" />
+ <panel_camera_item.selected_picture
+ image_name="MouseLook_View_On" />
+ </panel_camera_item>
+ <combo_box
+ height="23"
+ left="0"
+ mouse_opaque="true"
+ name="preset_combo"
+ top_pad="10"
+ width="136">
+ <combo_list
+ mouse_wheel_opaque="true"/>
+ <combo_box.item
+ label="Use preset"
+ name="Use preset"
+ value="default" />
+ </combo_box>
+ <button
+ height="16"
+ width="16"
+ layout="topleft"
+ mouse_opaque="true"
+ name="gear_btn"
+ tool_tip="My Camera Presets"
+ top_delta="3"
+ left_pad="10"
+ image_selected="Icon_Gear"
+ image_pressed="Icon_Gear"
+ image_unselected="Icon_Gear"
+ is_toggle="true">
+ <button.commit_callback
+ function="CameraPresets.ShowPresetsList"/>
+ </button>
+ <button
+ follows="top|left"
+ height="25"
+ label="Save as preset..."
+ layout="topleft"
+ left="0"
+ name="save_preset_btn"
+ top_pad="18"
+ width="150">
+ <button.commit_callback
+ function="CameraPresets.Save"/>
+ </button>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_camera_presets.xml b/indra/newview/skins/default/xui/en/floater_camera_presets.xml
new file mode 100644
index 0000000000..930357f568
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_camera_presets.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ height="200"
+ min_height="150"
+ title="MY CAMERA PRESETS"
+ layout="topleft"
+ name="floater_camera_presets"
+ single_instance="true"
+ min_width="185"
+ width="250">
+ <flat_list_view
+ allow_select="true"
+ follows="all"
+ height="165"
+ layout="topleft"
+ left="3"
+ multi_select="false"
+ name="preset_list"
+ top="20"
+ width="245" />
+ </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
new file mode 100644
index 0000000000..dcedaceaeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -0,0 +1,113 @@
+<?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="305"
+ layout="topleft"
+ name="create_landmark"
+ width="330">
+ <string name="favorites_bar">
+ Favorites bar
+ </string>
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="20"
+ name="title_label"
+ top="5"
+ font="SansSerifLargeBold"
+ value="Landmark added"
+ width="290" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="20"
+ name="name_label"
+ top_pad="10"
+ value="Name"
+ width="290" />
+ <line_editor
+ follows="left|top"
+ height="22"
+ layout="topleft"
+ max_length_bytes="63"
+ name="title_editor"
+ prevalidate_callback="ascii"
+ text_readonly_color="white"
+ top_pad="5"
+ width="290" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ name="folder_label"
+ top_pad="10"
+ value="Landmark location:"
+ width="290" />
+ <combo_box
+ follows="bottom|left"
+ height="23"
+ layout="topleft"
+ name="folder_combo"
+ top_pad="2"
+ width="290" />
+ <text
+ follows="left|top"
+ layout="topleft"
+ top_pad="6"
+ left="20"
+ name="new_folder_textbox"
+ height="20"
+ parse_urls="true"
+ skip_link_underline="true"
+ wrap="true">
+ [secondlife:/// Create new folder]
+ </text>
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ name="notes_label"
+ top_pad="10"
+ value="My notes"
+ width="290" />
+ <text_editor
+ bg_readonly_color="DkGray0"
+ follows="all"
+ height="75"
+ layout="topleft"
+ max_length="127"
+ name="notes_editor"
+ spellcheck="true"
+ text_readonly_color="white"
+ text_type="ascii_with_newline"
+ top_pad="5"
+ width="290"
+ wrap="true" />
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="OK"
+ layout="topleft"
+ mouse_opaque="false"
+ name="ok_btn"
+ top_pad="10"
+ left="19"
+ width="140" />
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ left_pad="12"
+ mouse_opaque="false"
+ name="cancel_btn"
+ width="140" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml
deleted file mode 100644
index b5de4166f6..0000000000
--- a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<floater
- legacy_header_height="18"
- height="130"
- help_topic=""
- layout="topleft"
- name="Delete Env Preset"
- save_rect="true"
- title="DELETE ENV PRESET"
- width="550">
-
- <string name="title_water">Delete Water Preset</string>
- <string name="title_sky">Delete Sky Preset</string>
- <string name="title_day_cycle">Delete Day Cycle</string>
-
- <string name="label_water">Preset:</string>
- <string name="label_sky">Preset:</string>
- <string name="label_day_cycle">Day cycle:</string>
-
- <string name="msg_confirm_deletion">Are you sure you want to delete the selected preset?</string>
- <string name="msg_sky_is_referenced">Cannot remove a preset that is referenced by some day cycle(s).</string>
-
- <string name="combo_label">-Select a preset-</string>
-
- <text
- follows="top|left|right"
- font="SansSerif"
- height="10"
- layout="topleft"
- left="50"
- name="label"
- top="60"
- width="60">
- Preset:
- </text>
- <combo_box
- follows="top|left"
- layout="topleft"
- left_pad="10"
- name="preset_combo"
- top_delta="-5"
- width="200"/>
- <button
- follows="bottom|right"
- height="23"
- label="Delete"
- layout="topleft"
- left_pad="15"
- name="delete"
- width="70"/>
- <button
- follows="bottom|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="5"
- name="cancel"
- width="70"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_delete_pref_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_pref_preset.xml
index 0688fdb42c..3360d7bec9 100644
--- a/indra/newview/skins/default/xui/en/floater_delete_pref_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_delete_pref_preset.xml
@@ -4,7 +4,7 @@
height="130"
help_topic="floater_delete_preset"
layout="topleft"
- name="Delete Pref Preset"
+ name="delete_pref_preset"
save_rect="true"
title="DELETE PREF PRESET"
width="300">
diff --git a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml
deleted file mode 100644
index d9a3ad0c4b..0000000000
--- a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml
+++ /dev/null
@@ -1,485 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="381"
- layout="topleft"
- name="Edit Day cycle"
- help_topic="day_presets"
- save_rect="true"
- title="Edit Day Cycle"
- width="705">
-
- <string name="title_new">Create a New Day Cycle</string>
- <string name="title_edit">Edit Day Cycle</string>
- <string name="hint_new">Name your day cycle, adjust the controls to create it, and click "Save".</string>
- <string name="hint_edit">To edit your day cycle, adjust the controls below and click "Save".</string>
- <string name="combo_label">-Select a preset-</string>
-
- <text
- follows="top|left|right"
- height="10"
- layout="topleft"
- left="10"
- name="hint"
- top="25"
- width="685" />
- <text
- follows="top|left|right"
- font="SansSerif"
- height="10"
- layout="topleft"
- left="10"
- name="label"
- top_pad="25"
- width="120">
- Preset Name:
- </text>
- <combo_box
- allow_text_entry="true"
- follows="top|left"
- layout="topleft"
- left_pad="10"
- max_chars="100"
- name="day_cycle_combo"
- top_delta="-5"
- width="200" />
- <line_editor
- height="20"
- left_delta="0"
- name="day_cycle_name"
- top_delta="0"
- visible="true"
- width="200" />
- <text
- follows="top|left|right"
- height="95"
- layout="topleft"
- left_pad="10"
- name="note"
- top_delta="0"
- width="345"
- wrap="true">
- Note: if you change the name of your preset, you will be creating a new preset and the existing preset will not be changed.
- </text>
- <!--======== Controls panel ========-->
- <text
- follows="left|top|right"
- height="10"
- layout="topleft"
- left="10"
- name="hint_item1"
- top="100"
- width="300">
- - Click on a tab to edit the specific sky settings and time.
- </text>
- <text
- follows="left|top|right"
- height="10"
- layout="topleft"
- name="hint_item2"
- top_pad="10"
- width="300">
- - Click and drag the tabs to set the transition times.
- </text>
- <text
- follows="left|top|right"
- height="10"
- layout="topleft"
- name="hint_item3"
- top_pad="10"
- width="300">
- - Use the scrubber to preview your day cycle.
- </text>
- <panel
- follows="top|left"
- height="100"
- name="day_cycle_slider_panel"
- layout="topleft"
- left_delta="25"
- top_pad="15"
- width="660">
- <multi_slider
- can_edit_text="true"
- control_name="WLTimeSlider"
- decimal_digits="0"
- draw_track="false"
- follows="bottom"
- height="10"
- increment="0.0833333"
- initial_value="0"
- layout="topleft"
- left="20"
- max_sliders="20"
- max_val="24"
- name="WLTimeSlider"
- show_text="false"
- top_pad="0"
- use_triangle="true"
- width="525" />
- <multi_slider
- can_edit_text="true"
- control_name="WLDayCycleKeys"
- decimal_digits="0"
- follows="bottom"
- height="10"
- increment="0.0833333"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- max_sliders="20"
- max_val="24"
- name="WLDayCycleKeys"
- show_text="false"
- top_pad="15"
- width="525" />
- <button
- height="20"
- label="Add Key"
- label_selected="Add Key"
- layout="topleft"
- left_pad="20"
- name="WLAddKey"
- top_delta="-18"
- width="96" />
- <button
- height="20"
- label="Delete Key"
- label_selected="Delete Key"
- layout="topleft"
- name="WLDeleteKey"
- top_pad="5"
- width="96" />
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left="8"
- name="WL12am"
- top="74"
- width="55">
- 12am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL3am"
- top_delta="0"
- width="55">
- 3am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL6am"
- top_delta="0"
- width="55">
- 6am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL9amHash"
- top_delta="0"
- width="55">
- 9am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL12pmHash"
- top_delta="0"
- width="55">
- 12pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL3pm"
- top_delta="0"
- width="55">
- 3pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL6pm"
- top_delta="0"
- width="55">
- 6pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL9pm"
- top_delta="0"
- width="55">
- 9pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="10"
- name="WL12am2"
- top_delta="0"
- width="55">
- 12am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left="20"
- name="WL12amHash"
- top="54"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="11"
- layout="topleft"
- left_pad="59"
- name="WL3amHash"
- top_delta="3"
- width="6">
- I
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="59"
- name="WL6amHash"
- top_delta="-3"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="11"
- layout="topleft"
- left_pad="59"
- name="WL9amHash2"
- top_delta="3"
- width="6">
- I
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="59"
- name="WL12pmHash2"
- top_delta="-3"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="11"
- layout="topleft"
- left_pad="59"
- name="WL3pmHash"
- top_delta="3"
- width="6">
- I
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="59"
- name="WL6pmHash"
- top_delta="-3"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="11"
- layout="topleft"
- left_pad="59"
- name="WL9pmHash"
- top_delta="3"
- width="6">
- I
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="59"
- name="WL12amHash2"
- top_delta="-3"
- width="6">
- |
- </text>
- </panel>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="192"
- name="WLCurKeyPresetText"
- top_pad="10"
- width="80">
- Sky Setting:
- </text>
- <combo_box
- height="18"
- label="Preset"
- layout="topleft"
- left_pad="5"
- name="WLSkyPresets"
- width="205" />
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-40"
- name="WLCurKeyTimeText"
- top_pad="15"
- width="35">
- Time:
- </text>
- <time
- follows="left|top"
- height="16"
- label_width="0"
- layout="topleft"
- left_pad="3"
- name="time"
- top_delta="-1"
- value="6:00 AM"
- width="75"/>
- <view_border
- bevel_style="none"
- follows="top|left"
- height="0"
- layout="topleft"
- left="10"
- name="horiz_separator"
- top_pad="20"
- width="685"/>
- <loading_indicator
- height="23"
- layout="topleft"
- left="25"
- name="progress_indicator"
- top="350"
- visible="false"
- width="23" />
- <check_box
- follows="top|left"
- height="10"
- label="Make this my new day cycle"
- layout="topleft"
- left="310"
- name="make_default_cb"
- top_delta="13"
- width="230"/>
- <button
- follows="bottom|right"
- height="23"
- label="Save"
- layout="topleft"
- left_pad="0"
- name="save"
- top_delta="-13"
- width="70"/>
- <button
- follows="bottom|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="15"
- name="cancel"
- top_delta="0"
- width="70"/>
- </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..c609e3bd3a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,651 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ layout="topleft"
+ name="env_edit_extdaycycle"
+ help_topic="day_presets"
+ save_rect="false"
+ title="Edit Day Cycle"
+ width="705"
+ height="700"
+ min_width="705"
+ min_height="700"
+ single_instance="true"
+ can_resize="false">
+
+ <!-- obsolete?, add as hint for 'save' button? -->
+ <string name="title_new">Create a New Day Cycle</string>
+ <string name="title_edit">Edit Day Cycle</string>
+ <string name="hint_new">Name your day cycle, adjust the controls to create it, and click "Save".</string>
+ <string name="hint_edit">To edit your day cycle, adjust the controls below and click "Save".</string>
+
+ <!-- Substitutions -->
+ <string name="time_label">([HH]:[MM])</string>
+ <string name="sky_track_label">Sky [ALT]</string>
+ <string name="sky_label">Sky</string>
+ <string name="water_label">Water</string>
+
+ <string name="commit_parcel">Apply To Parcel</string>
+ <string name="commit_region">Apply To Region</string>
+
+ <!-- Layout -->
+ <layout_stack name="outer_stack"
+ width="705"
+ height="700"
+ follows="all"
+ animate="false"
+ top="0"
+ orientation="vertical">
+ <layout_panel name="name_and_import"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ min_height="29"
+ background_visible="false">
+ <!-- This layout_panel is for loading legacy presets -->
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="10"
+ layout="topleft"
+ name="label"
+ left="15"
+ top="5"
+ width="105">
+ Day Cycle Name:
+ </text>
+ <line_editor
+ follows="top|left"
+ layout="topleft"
+ left_pad="10"
+ max_length_bytes="100"
+ name="day_cycle_name"
+ prevalidate_callback="ascii"
+ top="5"
+ width="200"
+ height="21" />
+ <button
+ height="23"
+ label="Import"
+ follows="right|top"
+ right="-10"
+ font="SansSerif"
+ top_delta="0"
+ name="btn_import"
+ tool_tip="Import legacy settings from disk."
+ width="96" />
+ </layout_panel>
+ <layout_panel name="content"
+ border="false"
+ auto_resize="true"
+ user_resize="false"
+ background_visible="false">
+ <layout_stack name="content_stack"
+ width="705"
+ follows="all"
+ animate="false"
+ top="0"
+ orientation="vertical">
+ <layout_panel name="timeline_track_selection"
+ border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ height="150"
+ min_height="0"
+ visible="true">
+ <panel name="timeline_layers"
+ border="false"
+ follows="left|top"
+ height="150"
+ width="110"
+ top_pad="0"
+ min_height="0"
+ visible="true">
+ <button
+ follows="left|top"
+ height="23"
+ label="Sky 4"
+ layout="topleft"
+ top_pad="5"
+ left="10"
+ name="sky4_track"
+ width="100">
+ <button.commit_callback
+ function="DayCycle.Track"
+ parameter="4" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Sky 3"
+ layout="topleft"
+ top_pad="0"
+ left="10"
+ name="sky3_track"
+ width="100">
+ <button.commit_callback
+ function="DayCycle.Track"
+ parameter="3" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Sky 2"
+ layout="topleft"
+ top_pad="0"
+ left="10"
+ name="sky2_track"
+ width="100">
+ <button.commit_callback
+ function="DayCycle.Track"
+ parameter="2" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Ground Level"
+ layout="topleft"
+ top_pad="0"
+ left="10"
+ name="sky1_track"
+ width="100">
+ <button.commit_callback
+ function="DayCycle.Track"
+ parameter="1" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Water"
+ layout="topleft"
+ top_pad="0"
+ left="10"
+ name="water_track"
+ width="100">
+ <button.commit_callback
+ function="DayCycle.Track"
+ parameter="0" />
+ </button>
+ </panel>
+ <panel name="timeline"
+ border="true"
+ follows="left|top"
+ height="150"
+ min_height="0"
+ width="595"
+ min_width="595"
+ left_pad="0"
+ visible="true">
+ <!-- Todo: These 5 tests might be subjected to a change to be dynamically generated, consider using layout_stack to get dynamic width adjustment-->
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="p0"
+ top_pad="5"
+ value="0% [DSC]"
+ width="90" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_delta="117"
+ name="p1"
+ top_delta="0"
+ value="25% [DSC]"
+ width="90" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_delta="122"
+ name="p2"
+ top_delta="0"
+ value="50% [DSC]"
+ width="90" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_delta="122"
+ name="p3"
+ top_delta="0"
+ value="75% [DSC]"
+ width="90" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_delta="122"
+ name="p4"
+ top_delta="0"
+ value="100% [DSC]"
+ width="90" />
+ <multi_slider
+ decimal_digits="0"
+ draw_track="false"
+ follows="bottom"
+ height="10"
+ increment="0.005"
+ overlap_threshold="0.026"
+ initial_value="0"
+ layout="topleft"
+ left="10"
+ max_sliders="1"
+ max_val="1"
+ name="WLTimeSlider"
+ show_text="false"
+ top_pad="0"
+ use_triangle="true"
+ width="525" />
+
+ <multi_slider
+ decimal_digits="0"
+ follows="bottom"
+ height="10"
+ increment="0.005"
+ overlap_threshold="0.026"
+ loop_overlap="true"
+ initial_value="0"
+ layout="topleft"
+ left="10"
+ max_sliders="20"
+ max_val="1"
+ name="WLDayCycleFrames"
+ show_text="false"
+ top_pad="15"
+ width="525" />
+
+ <text
+ follows="left|bottom"
+ height="25"
+ layout="topleft"
+ left_pad="0"
+ name="current_time"
+ value="[PRCNT]% [DSC]"
+ top_delta="-5"
+ width="56"
+ word_wrap="true"/>
+
+ <layout_stack
+ follows="all"
+ height="200"
+ animate="false"
+ top_pad="0"
+ left="0"
+ orientation="horizontal">
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ height="150"
+ width="200"
+ min_height="0"
+ visible="true">
+ <button
+ follows="top|left"
+ height="23"
+ width="110"
+ label="Clone Track From"
+ left="10"
+ top_pad="10"
+ name="copy_track" />
+ <button
+ follows="top|left"
+ height="23"
+ width="110"
+ label="Load Track From"
+ top_pad="0"
+ left_delta="0"
+ name="load_track" />
+ <button
+ follows="top|left"
+ height="23"
+ width="110"
+ label="Clear Track"
+ top_pad="0"
+ left_delta="0"
+ name="clear_track" />
+
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ height="150"
+ width="200"
+ min_height="0"
+ visible="true">
+ <layout_stack
+ name="progress_control"
+ follows="top|left"
+ height="25"
+ width="83"
+ layout="topleft"
+ animate="false"
+ left="31"
+ top="40"
+ orientation="horizontal">
+
+ <layout_panel
+ name="skip_back"
+ mouse_opaque="false"
+ auto_resize="false"
+ layout="topleft"
+ top="0"
+ height="25"
+ min_width="25"
+ width="25">
+ <button
+ name="skip_back_btn"
+ follows="top"
+ image_overlay="SkipBackward_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ auto_resize="false"
+ width="25"
+ height="25"
+ layout="topleft"
+ tool_tip="Step back"
+ top="0"
+ left="0">
+ <button.commit_callback
+ function="DayCycle.PlayActions"
+ parameter="back" />
+ </button>
+ </layout_panel>
+
+ <layout_panel
+ name="play_layout"
+ mouse_opaque="false"
+ auto_resize="false"
+ layout="topleft"
+ top="0"
+ height="25"
+ min_width="25"
+ width="25">
+ <button
+ name="play_btn"
+ follows="top"
+ image_overlay="Play_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ auto_resize="false"
+ layout="topleft"
+ height="25"
+ width="25"
+ left="0"
+ top="0">
+ <button.commit_callback
+ function="DayCycle.PlayActions"
+ parameter="play" />
+ </button>
+ </layout_panel>
+
+ <layout_panel
+ name="pause_layout"
+ mouse_opaque="false"
+ auto_resize="false"
+ layout="topleft"
+ top="0"
+ height="25"
+ min_width="25"
+ width="25"
+ visible="false">
+ <button
+ name="pause_btn"
+ follows="top"
+ image_overlay="Pause_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ auto_resize="false"
+ layout="topleft"
+ height="25"
+ width="25"
+ left="0"
+ top="0">
+ <button.commit_callback
+ function="DayCycle.PlayActions"
+ parameter="pause" />
+ </button>
+ </layout_panel>
+
+ <layout_panel
+ name="skip_forward"
+ mouse_opaque="false"
+ auto_resize="false"
+ layout="topleft"
+ top="0"
+ height="25"
+ min_width="25"
+ width="25">
+ <button
+ name="skip_forward_btn"
+ follows="top"
+ image_overlay="SkipForward_Off"
+ image_disabled="PushButton_Disabled"
+ image_disabled_selected="PushButton_Disabled"
+ image_selected="PushButton_Selected"
+ image_unselected="PushButton_Off"
+ hover_glow_amount="0.15"
+ width="25"
+ height="25"
+ layout="topleft"
+ tool_tip="Step forward"
+ top="0">
+ <button.commit_callback
+ function="DayCycle.PlayActions"
+ parameter="forward" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ width="190"
+ height="150"
+ min_height="0"
+ visible="true">
+ <button
+
+ follows="top|right"
+ height="23"
+ width="90"
+ right="-10"
+ top_pad="10"
+ label="Add [FRAME]"
+ name="add_frame" />
+ <button
+ follows="top|left"
+ height="23"
+ width="90"
+ label="Load [FRAME]"
+ top_pad="0"
+ left_delta="0"
+ name="btn_load_frame" />
+ <button
+ follows="left|top"
+ height="23"
+ width="90"
+ label="Delete [FRAME]"
+ top_pad="0"
+ left_delta="0"
+ name="delete_frame" />
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls"
+ auto_resize="false"
+ user_resize="false"
+ height="30"
+ width="700"
+ min_height="30"
+ visible="true">
+ <!--bg_alpha_color="blue"
+ background_visible="true" -->
+ <text
+ name="icn_lock_edit"
+ follows="bottom"
+ height="10"
+ layout="bottomleft"
+ left_delta="15"
+ top_pad="15"
+ font="SansSerif"
+ text_color="Yellow"
+ width="500">
+ Select a key frame from the timeline above to edit settings.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water"
+ auto_resize="true"
+ user_resize="false"
+ height="420"
+ width="700"
+ min_height="0"
+ visible="false">
+ <tab_container
+ follows="all"
+ halign="left"
+ height="420"
+ layout="topleft"
+ left="0"
+ name="water_tabs"
+ tab_position="top"
+ tab_width="140"
+ tab_padding_right="3"
+ top_pad="0"
+ width="700">
+ <panel
+ border="true"
+ class="panel_settings_water"
+ filename="panel_settings_water.xml"
+ label="Water"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky"
+ auto_resize="true"
+ user_resize="false"
+ height="420"
+ width="700"
+ min_height="0"
+ visible="true">
+ <tab_container
+ follows="all"
+ halign="left"
+ height="420"
+ visible="true"
+ layout="topleft"
+ left="0"
+ name="sky_tabs"
+ tab_position="top"
+ tab_width="140"
+ tab_padding_right="3"
+ top_pad="0"
+ width="700">
+ <panel
+ border="true"
+ class="panel_settings_atmos"
+ filename="panel_settings_sky_atmos.xml"
+ label="Atmosphere &amp; Lighting"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="atmosphere_panel" />
+ <panel
+ border="true"
+ class="panel_settings_cloud"
+ filename="panel_settings_sky_clouds.xml"
+ label="Clouds"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="clouds_panel" />
+ <panel
+ border="true"
+ class="panel_settings_sunmoon"
+ filename="panel_settings_sky_sunmoon.xml"
+ label="Sun &amp; Moon"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="moon_panel" />
+ <!-- added programatically so it doesn't show up whether we want it or not
+ <panel
+ border="true"
+ class="panel_settings_density"
+ filename="panel_settings_sky_density.xml"
+ label="Density"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="density_panel" />
+ -->
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons"
+ auto_resize="false"
+ user_resize="false"
+ height="26"
+ min_height="26"
+ visible="true"
+ width="700">
+ <button
+ follows="top|left"
+ height="23"
+ label="Save"
+ left="200"
+ top_pad="0"
+ name="save_btn"
+ width="156" />
+
+ <button
+ follows="top|left"
+ height="23"
+ name="btn_flyout"
+ label=""
+ layout="topleft"
+ left_pad="-20"
+ top="0"
+ image_selected="SegmentedBtn_Right_Selected_Press"
+ image_unselected="SegmentedBtn_Right_Off"
+ image_pressed="SegmentedBtn_Right_Press"
+ image_pressed_selected="SegmentedBtn_Right_Selected_Press"
+ image_overlay="Arrow_Small_Up"
+ width="20"/>
+
+ <button
+ follows="top|left"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ left_pad="10"
+ name="cancel_btn"
+ width="150" />
+
+ </layout_panel>
+ </layout_stack>
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml
index 52084e5f8e..3570456b44 100644
--- a/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml
@@ -4,18 +4,16 @@
legacy_header_height="225"
can_minimize="true"
can_close="true"
- can_resize="true"
- min_height="65"
- min_width="515"
- height="65"
+ can_resize="false"
+ height="80"
+ width="515"
layout="topleft"
name="HoverHeight"
single_instance="true"
help_topic="hover_height"
save_rect="true"
save_visibility="true"
- title="SET HOVER HEIGHT"
- width="515">
+ title="SET HOVER HEIGHT">
<slider
enabled="false"
control_name="HoverHeightSlider"
@@ -34,4 +32,13 @@
can_edit_text="true"
>
</slider>
+ <check_box
+ control_name="HoverHeightAffectsCamera"
+ follows="all"
+ height="15"
+ label="Bind Camera view"
+ layout="topleft"
+ name="BindCameraCheck"
+ top_pad="7"
+ width="237"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml
deleted file mode 100644
index 56233d91ee..0000000000
--- a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml
+++ /dev/null
@@ -1,953 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="375"
- layout="topleft"
- name="Edit Sky Preset"
- help_topic="sky_preset"
- save_rect="true"
- title="Edit Sky Preset"
- width="840">
-
- <string name="title_new">Create a New Sky Preset</string>
- <string name="title_edit">Edit Sky Preset</string>
- <string name="hint_new">Name your preset, adjust the controls to create it, and click "Save".</string>
- <string name="hint_edit">To edit your sky preset, adjust the controls and click "Save".</string>
- <string name="combo_label">-Select a preset-</string>
-
- <text
- follows="top|left|right"
- height="10"
- layout="topleft"
- left="30"
- name="hint"
- top="25"
- width="700">
- To edit your preset, adjust the controls then click "Save"
- </text>
- <text
- follows="top|left|right"
- font="SansSerif"
- height="10"
- layout="topleft"
- left="30"
- name="label"
- top_pad="25"
- width="120">
- Preset Name:
- </text>
- <combo_box
- allow_text_entry="true"
- follows="top|left"
- layout="topleft"
- left_pad="10"
- max_chars="100"
- name="sky_preset_combo"
- top_delta="-5"
- width="200"/>
- <line_editor
- height="20"
- left_delta="0"
- name="sky_preset_name"
- top_delta="0"
- width="200" />
- <text
- follows="top|left|right"
- height="40"
- layout="topleft"
- left_pad="10"
- name="note"
- top_delta="0"
- width="405"
- wrap="true">
- Note: if you change the name of your preset, you will be creating a new preset and the existing preset will not be changed.
- </text>
- <!--======== Controls panel ========-->
- <view_border
- bevel_style="none"
- follows="top|left"
- height="203"
- layout="topleft"
- left="25"
- name="panel_water_preset"
- top="122"
- visible="true"
- width="790"/>
- <tab_container
- follows="left|top"
- height="225"
- halign="center"
- layout="topleft"
- left="22"
- name="WindLight Tabs"
- tab_position="top"
- top="101"
- width="794">
- <panel
- border="true"
- bevel_style="none"
- follows="left|top|right|bottom"
- height="196"
- label="ATMOSPHERE"
- layout="topleft"
- left="1"
- help_topic="sky_preset_atmosphere"
- mouse_opaque="false"
- name="Atmosphere"
- top="60"
- width="698">
-
- <!--======== Tab Panel I. I conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="40"
- name="BHText"
- top="25"
- width="200">
- Blue Horizon
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="0"
- name="WLBlueHorizon"
- top_pad="6"
- width="60" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="0"
- top_pad="20"
- name="BDensText"
- width="200">
- Haze Horizon
- </text>
- <slider
- control_name="WLHazeHorizon"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.25"
- layout="topleft"
- left_delta="0"
- top_pad="6"
- name="WLHazeHorizon"
- width="200" />
-
- <!--======== Tab Panel I. II conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="55"
- name="BDensText2"
- top="25"
- width="200">
- Blue Density
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="0"
- name="WLBlueDensity"
- top_pad="6"
- width="60" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="0"
- name="HDText"
- top_pad="20"
- width="200">
- Haze Density
- </text>
- <slider
- control_name="WLHazeDensity"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.7"
- layout="topleft"
- left_delta="0"
- max_val="4"
- name="WLHazeDensity"
- top_pad="6"
- width="200" />
-
- <!--======== Tab Panel I. III conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="55"
- name="DensMultText"
- top="25"
- width="200">
- Density Multiplier
- </text>
- <slider
- control_name="WLDensityMult"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.1"
- layout="topleft"
- left_delta="15"
- max_val="0.9"
- name="WLDensityMult"
- top_pad="6"
- width="200" />
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="WLDistanceMultText"
- top_pad="20"
- width="200">
- Distance Multiplier
- </text>
- <slider
- control_name="WLDistancMult"
- decimal_digits="1"
- follows="left|top"
- height="10"
- initial_value="1.0"
- layout="topleft"
- left_delta="15"
- max_val="100"
- name="WLDistanceMult"
- top_pad="6"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="MaxAltText"
- top_pad="20"
- width="200">
- Max Altitude
- </text>
- <slider
- control_name="WLMaxAltitude"
- decimal_digits="0"
- follows="left|top"
- height="10"
- increment="1"
- initial_value="500"
- layout="topleft"
- left_delta="15"
- max_val="4000"
- name="WLMaxAltitude"
- top_pad="6"
- width="200" />
- </panel>
- <panel
- border="true"
- bevel_style="none"
- follows="left|top|right|bottom"
- height="196"
- label="LIGHTING"
- layout="topleft"
- left_delta="0"
- help_topic="sky_preset_lighting"
- name="Lighting"
- top_delta="4"
- width="698">
-
- <!--======== Tab Panel II. I conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="20"
- name="SLCText"
- top="25"
- width="150">
- Sun/Moon Color
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="10"
- name="WLSunlight"
- top_pad="6"
- width="60" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-10"
- name="WLAmbientText"
- top_pad="20"
- width="150">
- Ambient
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="10"
- name="WLAmbient"
- top_pad="6"
- width="60" />
-
- <!--======== Tab Panel II. II conlumn of controls ========-->
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="100"
- name="SunGlowText"
- top="25"
- width="200">
- Sun Glow
- </text>
- <slider
- control_name="WLGlowB"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.1"
- label="Focus "
- layout="topleft"
- left_delta="10"
- max_val="0.5"
- name="WLGlowB"
- top_pad="6"
- width="200" />
- <slider
- control_name="WLGlowR"
- decimal_digits="2"
- follows="top|left"
- height="10"
- increment="0.01"
- initial_value="0.25"
- label="Size "
- layout="topleft"
- left_delta="0"
- max_val="1.99"
- min_val="1"
- name="WLGlowR"
- top_pad="6"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-10"
- name="WLStarText"
- top_pad="20"
- width="200">
- Star Brightness
- </text>
- <slider
- control_name="WLStarAlpha"
- decimal_digits="2"
- follows="top|left"
- height="10"
- increment="0.01"
- initial_value="0"
- layout="topleft"
- left_delta="10"
- max_val="2"
- name="WLStarAlpha"
- top_pad="6"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-10"
- name="SceneGammaText"
- top_pad="20"
- width="200">
- Scene Gamma
- </text>
- <slider
- control_name="WLGamma"
- decimal_digits="2"
- follows="top|left"
- height="10"
- increment="0.01"
- initial_value="2.0"
- layout="topleft"
- left_delta="10"
- max_val="10"
- name="WLGamma"
- top_pad="6"
- width="200" />
-
- <!--======== Tab Panel II. III conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="60"
- name="TODText"
- top="25"
- width="200">
- Sun/Moon Position
- </text>
- <multi_slider
- can_edit_text="true"
- control_name="WLSunPos"
- decimal_digits="0"
- follows="bottom"
- height="10"
- increment="0.0833333"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- max_sliders="1"
- max_val="24"
- name="WLSunPos"
- show_text="false"
- top_pad="0"
- width="300" />
-
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_delta="2"
- name="WL12amHash"
- top_pad="6"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="66"
- name="WL6amHash"
- top_delta="0"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="67"
- name="WL12pmHash2"
- top_delta="0"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="67"
- name="WL6pmHash"
- top_delta="0"
- width="6">
- |
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- font="SansSerif"
- height="14"
- layout="topleft"
- left_pad="67"
- name="WL12amHash2"
- top_delta="0"
- width="6">
- |
- </text>
-
-
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_delta="-300"
- name="WL12am"
- top="74"
- width="55">
- 12am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="20"
- name="WL6am"
- top_delta="0"
- width="55">
- 6am
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="15"
- name="WL12pmHash"
- top_delta="0"
- width="55">
- 12pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="18"
- name="WL6pm"
- top_delta="0"
- width="55">
- 6pm
- </text>
- <text
- type="string"
- length="1"
- border_visible="true"
- follows="left|top|right"
- height="16"
- layout="topleft"
- left_pad="15"
- name="WL12am2"
- top_delta="0"
- width="55">
- 12am
- </text>
-
- <time
- follows="left|top"
- height="16"
- label_width="0"
- layout="topleft"
- left_delta="-175"
- name="WLDayTime"
- top_pad="15"
- value="6:00 AM"
- width="75"/>
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-106"
- name="WLEastAngleText"
- top_pad="24"
- width="200">
- East Angle
- </text>
- <slider
- control_name="WLEastAngle"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.0"
- layout="topleft"
- left_delta="10"
- name="WLEastAngle"
- top_pad="6"
- width="200" />
-
- </panel>
- <panel
- border="true"
- bevel_style="none"
- follows="left|top|right|bottom"
- height="196"
- label="CLOUDS"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- help_topic="sky_preset_clouds"
- name="Clouds"
- top_delta="4"
- width="698">
-
- <!--======== Tab Panel III. I conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="40"
- name="WLCloudColorText"
- top="25"
- width="200">
- Cloud Color
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="0"
- name="WLCloudColor"
- top_pad="6"
- width="60" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="0"
- name="WLCloudColorText2"
- top_pad="20"
- width="200">
- Cloud XY/Density
- </text>
- <slider
- control_name="WLCloudX"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- label="X"
- layout="topleft"
- left_delta="0"
- top_pad="6"
- name="WLCloudX"
- width="200" />
- <slider
- control_name="WLCloudY"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- label="Y"
- layout="topleft"
- left_delta="0"
- top_pad="6"
- name="WLCloudY"
- width="200" />
- <slider
- control_name="WLCloudDensity"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="1.0"
- label="D"
- layout="topleft"
- left_delta="0"
- name="WLCloudDensity"
- top_pad="6"
- width="200" />
-
- <!--======== Tab Panel III. II conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="55"
- name="WLCloudCoverageText"
- top="15"
- width="200">
- Cloud Coverage
- </text>
- <slider
- control_name="WLCloudCoverage"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- layout="topleft"
- left_delta="15"
- name="WLCloudCoverage"
- top_pad="6"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="WLCloudScaleText"
- top_pad="20"
- width="200">
- Cloud Scale
- </text>
- <slider
- control_name="WLCloudScale"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="1.0"
- layout="topleft"
- left_delta="15"
- min_val="0.01"
- name="WLCloudScale"
- top_pad="6"
- width="200" />
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-13"
- name="WLCloudDetailText"
- top_pad="20"
- width="200">
- Cloud Detail (XY/Density)
- </text>
- <slider
- control_name="WLCloudDetailX"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- label="X"
- layout="topleft"
- left_delta="0"
- top_pad="6"
- name="WLCloudDetailX"
- width="200" />
- <slider
- control_name="WLCloudDetailY"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- label="Y"
- layout="topleft"
- left_delta="0"
- name="WLCloudDetailY"
- top_pad="6"
- width="200" />
- <slider
- control_name="WLCloudDetailDensity"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="1.0"
- label="D"
- layout="topleft"
- left_delta="0"
- name="WLCloudDetailDensity"
- top_pad="6"
- width="200" />
-
- <!--======== Tab Panel III. III conlumn of controls ========-->
-
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="55"
- name="WLCloudScrollXText"
- top="15"
- width="150">
- Cloud Scroll X
- </text>
- <check_box
- control_name="WLCloudLockX"
- follows="left|top"
- height="16"
- label="Lock"
- layout="topleft"
- left_delta="150"
- name="WLCloudLockX"
- top_delta="0"
- width="200" />
- <slider
- control_name="WLCloudScrollX"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- layout="topleft"
- left_delta="-135"
- max_val="10"
- min_val="-10"
- name="WLCloudScrollX"
- top_pad="6"
- width="200" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="WLCloudScrollYText"
- top_pad="20"
- width="150">
- Cloud Scroll Y
- </text>
- <check_box
- control_name="WLCloudLockY"
- follows="left|top"
- height="16"
- label="Lock"
- layout="topleft"
- left_delta="150"
- name="WLCloudLockY"
- width="200" />
- <slider
- control_name="WLCloudScrollY"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.5"
- layout="topleft"
- left_delta="-135"
- max_val="10"
- min_val="-10"
- name="WLCloudScrollY"
- top_pad="6"
- width="200" />
- </panel>
- </tab_container>
-<!--======== End of Controls panel ========-->
-
- <check_box
- follows="top|left"
- height="10"
- label="Make this preset my new sky setting"
- layout="topleft"
- left="380"
- name="make_default_cb"
- top_pad="30"
- width="280"/>
- <button
- follows="bottom|right"
- height="23"
- label="Save"
- layout="topleft"
- left_pad="0"
- name="save"
- width="70"/>
- <button
- follows="bottom|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="15"
- name="cancel"
- width="70"/>
- </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml
deleted file mode 100644
index 905983e7fa..0000000000
--- a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml
+++ /dev/null
@@ -1,448 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="375"
- layout="topleft"
- name="Edit Water Preset"
- help_topic="water_preset"
- save_rect="true"
- title="Edit Water Preset"
- width="725">
-
- <string name="title_new">Create a New Water Preset</string>
- <string name="title_edit">Edit a Water Preset</string>
- <string name="hint_new">Name your preset, adjust the controls to create it, and click "Save".</string>
- <string name="hint_edit">To edit your water preset, adjust the controls and click "Save".</string>
- <string name="combo_label">-Select a preset-</string>
-
- <text
- follows="top|left|right"
- height="10"
- layout="topleft"
- left="30"
- name="hint"
- top="25"
- width="680">
- To edit your preset, adjust the controls then click "Save"
- </text>
-
- <text
- follows="top|left|right"
- font="SansSerif"
- height="10"
- layout="topleft"
- left="30"
- name="label"
- top_pad="25"
- width="120">
- Preset Name:
- </text>
-
- <combo_box
- allow_text_entry="true"
- follows="top|left"
- layout="topleft"
- left_pad="10"
- max_chars="100"
- name="water_preset_combo"
- top_delta="-5"
- width="200"/>
-
- <line_editor
- height="20"
- left_delta="0"
- name="water_preset_name"
- top_delta="0"
- width="200" />
-
- <text
- follows="top|left|right"
- height="40"
- layout="topleft"
- left_pad="10"
- name="note"
- top_delta="0"
- width="340"
- wrap="true">
- Note: if you change the name of your preset, you will be creating a new preset and the existing preset will not be changed.
- </text>
-
- <!--======== Controls panel ========-->
- <panel
- border="false"
- bevel_style="none"
- follows="top|left"
- height="230"
- layout="topleft"
- left="10"
- name="panel_water_preset"
- top="100"
- width="700">
-
-<!--======== I conlumn of controls ========-->
- <text
- follows="left|top|right"
- height="10"
- font="SansSerif"
- layout="topleft"
- left="10"
- name="water_color_label"
- top="5"
- width="215">
- Water Fog Color
- </text>
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="37"
- label_height="0"
- layout="topleft"
- left_delta="15"
- name="WaterFogColor"
- top_pad="8"
- width="60" />
-
-
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- top_pad="10"
- name="water_fog_density_label"
- width="215">
- Fog Density Exponent
- </text>
- <slider
- decimal_digits="1"
- follows="left|top"
- height="10"
- initial_value="0"
- layout="topleft"
- left_delta="15"
- max_val="10"
- name="WaterFogDensity"
- top_pad="10"
- width="200"/>
-
-
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- top_pad="15"
- name="underwater_fog_modifier_label"
- width="215">
- Underwater Fog Modifier
- </text>
- <slider
- decimal_digits="1"
- follows="left|top"
- height="10"
- initial_value="0"
- layout="topleft"
- left_delta="15"
- max_val="10"
- name="WaterUnderWaterFogMod"
- top_pad="10"
- width="200"/>
-
-
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- name="BHText"
- top_pad="15"
- width="215">
- Big Wave Direction
- </text>
- <slider
- control_name="WaterWave1DirX"
- decimal_digits="2"
- follows="left|top"
- increment="0.01"
- initial_value="0.7"
- label="X"
- layout="topleft"
- max_val="4"
- min_val="-4"
- name="WaterWave1DirX"
- top_pad="10"
- width="216"/>
- <slider
- control_name="WaterWave1DirY"
- decimal_digits="2"
- follows="left|top"
- increment="0.01"
- initial_value="0.7"
- label="Y"
- layout="topleft"
- max_val="4"
- min_val="-4"
- name="WaterWave1DirY"
- top_pad="5"
- width="216"/>
-
-<!--======== II conlumn of controls ========-->
-
- <text
- follows="left|top|right"
- font="SansSerif"
- height="10"
- layout="topleft"
- left_pad="20"
- name="BDensText"
- top="5"
- width="215">
- Reflection Wavelet Scale
- </text>
- <slider
- control_name="WaterNormalScaleX"
- decimal_digits="1"
- follows="left|top"
- initial_value="0.7"
- layout="topleft"
- left_delta="15"
- max_val="10"
- name="WaterNormalScaleX"
- top_pad="10"
- width="200"/>
- <slider
- control_name="WaterNormalScaleY"
- decimal_digits="1"
- follows="left|top"
- initial_value="0.7"
- layout="topleft"
- max_val="10"
- name="WaterNormalScaleY"
- top_pad="6"
- width="200"/>
- <slider
- control_name="WaterNormalScaleZ"
- decimal_digits="1"
- follows="left|top"
- initial_value="0.7"
- layout="topleft"
- max_val="10"
- name="WaterNormalScaleZ"
- top_pad="6"
- width="200"/>
-
-
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- name="HDText"
- top_pad="16"
- width="215">
- Fresnel Scale
- </text>
- <slider
- control_name="WaterFresnelScale"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0.7"
- layout="topleft"
- left_delta="15"
- name="WaterFresnelScale"
- top_pad="10"
- width="200"/>
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- name="FresnelOffsetText"
- top_pad="15"
- width="215">
- Fresnel Offset
- </text>
- <slider
- control_name="WaterFresnelOffset"
- decimal_digits="2"
- follows="left"
- increment="0.01"
- initial_value="0.7"
- layout="topleft"
- left_delta="15"
- name="WaterFresnelOffset"
- top_pad="10"
- width="200"/>
-
-
- <text
- follows="left|top|right"
- font="SansSerif"
- layout="topleft"
- left_delta="-15"
- name="BHText2"
- top_pad="15"
- width="215">
- Little Wave Direction
- </text>
- <slider
- control_name="WaterWave2DirX"
- decimal_digits="2"
- follows="left|top"
- increment="0.01"
- initial_value="0.7"
- label="X"
- layout="topleft"
- max_val="4"
- min_val="-4"
- name="WaterWave2DirX"
- top_pad="10"
- width="216" />
- <slider
- control_name="WaterWave2DirY"
- decimal_digits="2"
- follows="left|top"
- increment="0.01"
- initial_value="0.7"
- label="Y"
- layout="topleft"
- max_val="4"
- min_val="-4"
- name="WaterWave2DirY"
- top_pad="6"
- width="216" />
-
-<!--======== III conlumn of contorls ========-->
-
- <text
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="20"
- name="DensMultText"
- top="5"
- width="215">
- Refract Scale Above
- </text>
- <slider
- control_name="WaterScaleAbove"
- decimal_digits="2"
- follows="left|top"
- increment="0.01"
- initial_value="0.1"
- layout="topleft"
- left_delta="15"
- name="WaterScaleAbove"
- top_pad="5"
- width="200" />
-
- <text
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="WaterScaleBelowText"
- top_pad="15"
- width="215">
- Refract Scale Below
- </text>
- <slider
- control_name="WaterScaleBelow"
- decimal_digits="2"
- follows="left|top"
- height="10"
- increment="0.01"
- initial_value="0"
- layout="topleft"
- left_delta="15"
- name="WaterScaleBelow"
- top_pad="5"
- width="200"/>
-
- <text
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="MaxAltText"
- top_pad="15"
- width="215">
- Blur Multiplier
- </text>
- <slider
- control_name="WaterBlurMult"
- follows="left|top"
- height="10"
- increment="0.001"
- initial_value="0"
- layout="topleft"
- left_delta="15"
- max_val="0.16"
- name="WaterBlurMult"
- top_pad="5"
- width="200"/>
-
- <text
- follows="left|top|right"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_delta="-15"
- name="BHText3"
- top_pad="15"
- width="215">
- Normal Map
- </text>
- <texture_picker
- height="80"
- layout="topleft"
- left_delta="15"
- name="WaterNormalMap"
- top_pad="5"
- width="100" />
- </panel>
-<!--======== End of Controls panel ========-->
-
- <view_border
- bevel_style="none"
- follows="top|left"
- height="0"
- layout="topleft"
- left="10"
- name="horiz_separator"
- top_pad="5"
- width="700"/>
- <check_box
- follows="top|left"
- height="10"
- label="Make this preset my new water setting"
- layout="topleft"
- left="275"
- name="make_default_cb"
- top_pad="20"
- width="280"/>
- <button
- follows="bottom|right"
- height="23"
- label="Save"
- layout="topleft"
- left_pad="0"
- name="save"
- width="70"/>
- <button
- follows="bottom|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="15"
- name="cancel"
- width="70"/>
-
- </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_environment_settings.xml b/indra/newview/skins/default/xui/en/floater_environment_settings.xml
deleted file mode 100644
index 1b1cafaca6..0000000000
--- a/indra/newview/skins/default/xui/en/floater_environment_settings.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="328"
- layout="topleft"
- name="Environment Editor Floater"
- help_topic="environment_editor_floater"
- save_rect="true"
- title="ENVIRONMENT SETTINGS"
- width="540">
-
- <text
- follows="top|left|right"
- height="15"
- layout="topleft"
- left="20"
- name="note"
- top="25"
- width="510"
- wrap="true">
- Use the options below to customize the environment settings for your viewer.
- </text>
-
- <view_border
- bevel_style="none"
- follows="top|left"
- height="237"
- layout="topleft"
- left="20"
- name="border"
- top_pad="8"
- width="500"/>
- <radio_group
- follows="top|left"
- height="45"
- layout="topleft"
- left_delta="10"
- name="region_settings_radio_group"
- top_delta="20"
- width="200">
- <radio_item
- label="Use region settings"
- layout="topleft"
- name="use_region_settings"/>
- <radio_item
- label="Customize my environment"
- layout="topleft"
- name="use_my_settings"
- top_pad="20"/>
- </radio_group>
-
- <panel
- height="170"
- layout="topleft"
- left="50"
- name="user_environment_settings"
- top_pad="0"
- width="470">
-
- <text
- follows="top|left|right"
- font="SansSerifItalic"
- height="15"
- layout="topleft"
- left_delta="0"
- name="note"
- top_pad="0"
- width="470"
- wrap="true">
- Note: your custom settings will not be visible to other users.
- </text>
-
- <!-- Water Setting -->
- <text
- name="water_settings_title"
- follows="top|left"
- height="16"
- layout="topleft"
- left="50"
- top="40"
- width="200">
- Water Setting
- </text>
- <combo_box
- follows="top|left"
- left_pad="2"
- name="water_settings_preset_combo"
- top_delta="-5"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
-
-
- <!-- Sky/Day Cycle Settings -->
- <text
- name="sky_dayc_settings_title"
- follows="top|left"
- height="16"
- layout="topleft"
- left="50"
- top_pad="20"
- width="100">
- Sky / Day Cycle
- </text>
- <radio_group
- layout="topleft"
- left_delta="50"
- name="sky_dayc_settings_radio_group"
- top_pad="10"
- height="50"
- width="150">
- <radio_item
- layout="topleft"
- label="Fixed sky"
- name="my_sky_settings"/>
- <radio_item
- layout="topleft"
- label="Day cycle"
- name="my_dayc_settings"
- top_pad="25"/>
- </radio_group>
- <combo_box
- follows="top|left"
- left_pad="2"
- name="sky_settings_preset_combo"
- top_delta="-7"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
- <combo_box
- follows="top|left"
- name="dayc_settings_preset_combo"
- top_delta="36"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
- </panel>
-
- <button
- follows="left|top"
- height="23"
- label="OK"
- layout="topleft"
- right="-130"
- name="ok_btn"
- top_pad="10"
- width="100" />
- <button
- follows="left|top"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="10"
- name="cancel_btn"
- width="100" />
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..a6e20880a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_tear_off="false"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_close="true"
+ can_dock="false"
+ bevel_style="in"
+ height="550"
+ layout="topleft"
+ name="Fixed Environment"
+ save_rect="true"
+ title="Fixed Environment"
+ save_visibility="false"
+ help_topic="fixed_environment"
+ single_instance="true"
+ width="750">
+ <string name="edit_sky">Edit Sky:</string>
+ <string name="edit_water">Edit Water:</string>
+ <layout_stack name="floater_stack"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ follows="left|top|right|bottom"
+ orientation="vertical">
+ <layout_panel name="info_panel"
+ auto_resize="false"
+ user_resize="false"
+ min_height="60">
+ <text
+ follows="left|top"
+ top_delta="30"
+ left_delta="10"
+ width="35"
+ height="20"
+ font="SansSerif">
+ Name:
+ </text>
+ <line_editor
+ follows="left|top"
+ top_delta="-2"
+ left_delta="45"
+ width="250"
+ name="settings_name"
+ prevalidate_callback="ascii"
+ max_length_chars="63"
+ height="20"/>
+ <button
+ height="23"
+ label="Load"
+ follows="left|top"
+ left_delta="260"
+ font="SansSerif"
+ top_delta="-2"
+ name="btn_load"
+ tool_tip="Load a settings from inventory"
+ width="96" />
+ <button
+ height="23"
+ label="Import"
+ follows="right|top"
+ right="-10"
+ font="SansSerif"
+ top_delta="0"
+ name="btn_import"
+ tool_tip="Import legacy settings from disk."
+ width="96" />
+ </layout_panel>
+ <layout_panel name="tab_area"
+ auto_resize="true"
+ user_resize="false"
+ height="11"
+ min_height="0"
+ visible="true">
+ <tab_container
+ follows="all"
+ halign="left"
+ layout="topleft"
+ left="0"
+ name="tab_settings"
+ tab_position="top"
+ tab_width="120"
+ tab_padding_right="3">
+ <!-- Tabs inserted here in code -->
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="button_panel"
+ follows="left|top|right|bottom"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ visible="true">
+ <layout_stack
+ follows="bottom|left|right"
+ height="23"
+ layout="topleft"
+ mouse_opaque="false"
+ name="button_bar_ls"
+ left="212"
+ orientation="horizontal"
+ top="0"
+ width="313">
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left="0"
+ mouse_opaque="false"
+ name="save_btn_lp"
+ auto_resize="true"
+ width="156">
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="Save"
+ left="1"
+ layout="topleft"
+ name="btn_commit"
+ top="0"
+ width="155" />
+ <button
+ follows="bottom|right"
+ height="23"
+ name="btn_flyout"
+ label=""
+ layout="topleft"
+ left_pad="-20"
+ tab_stop="false"
+ top="0"
+ image_selected="SegmentedBtn_Right_Selected_Press"
+ image_unselected="SegmentedBtn_Right_Off"
+ image_pressed="SegmentedBtn_Right_Press"
+ image_pressed_selected="SegmentedBtn_Right_Selected_Press"
+ image_overlay="Arrow_Small_Up"
+ width="20"/>
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left_pad="3"
+ mouse_opaque="false"
+ name="revert_btn_lp"
+ auto_resize="true"
+ width="147">
+ <button
+ follows="bottom|right"
+ height="23"
+ right="-1"
+ label="Cancel"
+ layout="topleft"
+ name="btn_cancel"
+ top="0"
+ tool_tip="Revert to last saved version"
+ width="147" />
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_forget_user.xml b/indra/newview/skins/default/xui/en/floater_forget_user.xml
new file mode 100644
index 0000000000..a9ec1b74a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_forget_user.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ height="258"
+ layout="topleft"
+ name="groups"
+ help_topic="forget_username"
+ title="REMEMBERED USERNAMES"
+ width="280">
+ <scroll_list
+ height="173"
+ layout="topleft"
+ left="12"
+ name="user_list"
+ top="24"
+ width="256">
+ <scroll_list.columns
+ name="user"
+ width="248" />
+ </scroll_list>
+ <button
+ height="20"
+ label="Forget"
+ label_selected="Forget"
+ layout="topleft"
+ left_delta="90"
+ name="forget"
+ top_pad="8"
+ width="80" />
+ <check_box
+ height="20"
+ label="Also delete local data for this username"
+ layout="topleft"
+ left="15"
+ name="delete_data"
+ top_pad="5"
+ width="260"
+ tool_tip="Deletes local files: chat history, last session screenshot, browser cookies, teleport history, toolbar settings, e t c. Some of local files are shared between grids."/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml
index 8c0077a8cc..baff8e1bc0 100644
--- a/indra/newview/skins/default/xui/en/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/en/floater_how_to.xml
@@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- can_resize="true"
- can_minimize="true"
- height="775"
+ can_resize="false"
+ can_minimize="false"
+ can_close="false"
+ height="525"
layout="topleft"
- min_height="360"
- left="10000"
- top="10"
- min_width="335"
name="floater_how_to"
- help_topic="how_to"
single_instance="true"
+ save_visibility="true"
save_rect="true"
- title="HOW TO"
- width="780"
+ title="WELCOME ISLAND GUIDEBOOK"
+ width="310"
+ rel_x="-0.469309"
+ rel_y="-0.011166"
filename="floater_web_content.xml"/> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index c64ee5565a..15f02ab9c3 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -267,6 +267,36 @@
right="-1">
<layout_panel
name="input_editor_layout_panel">
+ <avatar_icon
+ follows="left|bottom"
+ name="avatar_icon"
+ height="20"
+ default_icon_name="Generic_Person"
+ layout="topleft"
+ left="3"
+ bottom="-9"
+ visible="false"
+ width="20" />
+ <group_icon
+ follows="left|bottom"
+ name="group_chat_icon"
+ height="20"
+ default_icon_name="Generic_Group"
+ layout="topleft"
+ left="3"
+ bottom="-9"
+ visible="false"
+ width="20" />
+ <icon
+ follows="left|bottom"
+ height="20"
+ image_name="Nearby_chat_icon"
+ layout="topleft"
+ left="3"
+ bottom="-9"
+ name="nearby_chat_icon"
+ visible="false"
+ width="20"/>
<chat_editor
layout="topleft"
expand_lines_count="5"
@@ -280,7 +310,7 @@
spellcheck="true"
tab_group="3"
bottom="-8"
- left="5"
+ left_pad="5"
right="-5"
wrap="true" />
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml
index 44d2c14cc8..773d9aafc9 100644
--- a/indra/newview/skins/default/xui/en/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="460"
+ height="495"
layout="topleft"
name="Image Preview"
help_topic="image_preview"
@@ -120,8 +120,8 @@
Try saving image as 24 bit Targa (.tga).
</text>
<check_box
- control_name="LosslessJ2CUpload"
enabled="false"
+ initial_value="false"
follows="bottom|left"
height="16"
label="Use lossless compression"
@@ -148,4 +148,17 @@ Try saving image as 24 bit Targa (.tga).
name="ok_btn"
top_delta="0"
width="125" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="35"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ skip_link_underline="true"
+ name="info_text"
+ word_wrap="true"
+ top_pad="10"
+ width="270"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index 63334e2b24..802a6649c8 100644
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -13,7 +13,7 @@
width="400">
<floater.string
name="timeStamp">
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</floater.string>
<scroll_list
bottom="268"
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 ca1d299553..d783d1e23c 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="448"
+ height="466"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -195,6 +195,23 @@
name="check_snapshot"
top_delta="0"
width="126" />
+ <icon
+ height="16"
+ image_name="Inv_Settings"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_settings"
+ top="242"
+ width="16" />
+ <check_box
+ height="16"
+ label="Settings"
+ layout="topleft"
+ left_pad="2"
+ name="check_settings"
+ top_delta="0"
+ width="126" />
<button
follows="left|top"
height="20"
@@ -203,7 +220,7 @@
layout="topleft"
left="8"
name="All"
- top="242"
+ top="262"
width="100" />
<button
height="20"
@@ -257,7 +274,7 @@
width="260"/>
<check_box
height="16"
- top="332"
+ top="352"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -273,7 +290,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="350"
+ top="370"
width="144">
- OR -
</text>
@@ -281,7 +298,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="368"
+ top="388"
left="8"
width="270">
<radio_item
@@ -351,6 +368,6 @@
layout="topleft"
name="Close"
right="-6"
- top="414"
+ top="434"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index 3dfdf8e1a5..7d2cea1fe5 100644
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -8,27 +8,32 @@
title="JOYSTICK CONFIGURATION"
width="569">
<floater.string
- name="NoDevice">
- no device detected
+ name="JoystickDisabled">
+ None
</floater.string>
- <check_box
- bottom="38"
- height="10"
- control_name="JoystickEnabled"
- halign="left"
- label="Enable Joystick:"
+ <text
+ type="string"
layout="topleft"
+ follows="left|top"
+ halign="left"
+ height="12"
+ top="22"
left="14"
- name="enable_joystick"
- width="60" />
- <text
- bottom="32"
+ width="50"
+ mouse_opaque="false"
+ name="joystick_lbl">
+ Joystick:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ follows="left|top"
layout="topleft"
- left="120"
- name="joystick_type"
- width="380" />
+ name="joystick_combo"
+ top="19"
+ left_pad="4"
+ width="300"/>
<spinner
- bottom="48"
+ bottom="56"
height="10"
control_name="JoystickAxis1"
decimal_digits="0"
@@ -42,7 +47,7 @@
name="JoystickAxis1"
width="140" />
<spinner
- bottom="48"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis2"
decimal_digits="0"
@@ -56,7 +61,7 @@
name="JoystickAxis2"
width="140" />
<spinner
- bottom="48"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis0"
decimal_digits="0"
@@ -70,7 +75,7 @@
name="JoystickAxis0"
width="140" />
<spinner
- bottom="68"
+ bottom="76"
height="10"
control_name="JoystickAxis4"
decimal_digits="0"
@@ -84,7 +89,7 @@
name="JoystickAxis4"
width="140" />
<spinner
- bottom="68"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis5"
decimal_digits="0"
@@ -98,7 +103,7 @@
name="JoystickAxis5"
width="140" />
<spinner
- bottom="68"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis3"
decimal_digits="0"
@@ -112,7 +117,7 @@
name="JoystickAxis3"
width="140" />
<spinner
- bottom="88"
+ bottom="96"
height="10"
control_name="JoystickAxis6"
decimal_digits="0"
@@ -162,12 +167,12 @@
left="37"
mouse_opaque="false"
name="Control Modes:"
- top="110"
+ top="118"
width="102">
Control Modes:
</text>
<check_box
- bottom="127"
+ bottom="134"
height="10"
control_name="JoystickAvatarEnabled"
halign="center"
@@ -177,7 +182,7 @@
name="JoystickAvatarEnabled"
width="60" />
<check_box
- bottom="127"
+ bottom_delta="0"
height="10"
control_name="JoystickBuildEnabled"
halign="center"
@@ -187,7 +192,7 @@
name="JoystickBuildEnabled"
width="60" />
<check_box
- bottom="127"
+ bottom_delta="0"
height="10"
control_name="JoystickFlycamEnabled"
halign="center"
@@ -203,7 +208,7 @@
left="359"
name="axis_view"
show_label="true"
- top="135"
+ top="143"
width="200">
<stat_bar
bar_max="2"
@@ -266,7 +271,7 @@
<text
type="string"
length="1"
- bottom="144"
+ bottom="152"
halign="right"
layout="topleft"
left="3"
@@ -275,7 +280,7 @@
X Scale
</text>
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale1"
decimal_digits="2"
@@ -287,7 +292,7 @@
name="AvatarAxisScale1"
width="56" />
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale1"
decimal_digits="2"
@@ -299,7 +304,7 @@
name="BuildAxisScale1"
width="56" />
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale1"
decimal_digits="2"
@@ -313,7 +318,7 @@
<text
type="string"
length="1"
- bottom="164"
+ bottom="172"
halign="right"
layout="topleft"
left="3"
@@ -322,7 +327,7 @@
Y Scale
</text>
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale2"
decimal_digits="2"
@@ -334,7 +339,7 @@
name="AvatarAxisScale2"
width="56" />
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale2"
decimal_digits="2"
@@ -346,7 +351,7 @@
name="BuildAxisScale2"
width="56" />
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale2"
decimal_digits="2"
@@ -360,7 +365,7 @@
<text
type="string"
length="1"
- bottom="184"
+ bottom="192"
halign="right"
layout="topleft"
left="3"
@@ -369,7 +374,7 @@
Z Scale
</text>
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale0"
decimal_digits="2"
@@ -381,7 +386,7 @@
name="AvatarAxisScale0"
width="56" />
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale0"
decimal_digits="2"
@@ -393,7 +398,7 @@
name="BuildAxisScale0"
width="56" />
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale0"
decimal_digits="2"
@@ -407,7 +412,7 @@
<text
type="string"
length="1"
- bottom="204"
+ bottom="212"
halign="right"
layout="topleft"
left="3"
@@ -416,7 +421,7 @@
Pitch Scale
</text>
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale4"
decimal_digits="2"
@@ -428,7 +433,7 @@
name="AvatarAxisScale4"
width="56" />
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale4"
decimal_digits="2"
@@ -440,7 +445,7 @@
name="BuildAxisScale4"
width="56" />
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale4"
decimal_digits="2"
@@ -454,7 +459,7 @@
<text
type="string"
length="1"
- bottom="224"
+ bottom="232"
halign="right"
layout="topleft"
left="3"
@@ -463,7 +468,7 @@
Yaw Scale
</text>
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale5"
decimal_digits="2"
@@ -475,7 +480,7 @@
name="AvatarAxisScale5"
width="56" />
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale5"
decimal_digits="2"
@@ -487,7 +492,7 @@
name="BuildAxisScale5"
width="56" />
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale5"
decimal_digits="2"
@@ -501,7 +506,7 @@
<text
type="string"
length="1"
- bottom="244"
+ bottom="252"
halign="right"
layout="topleft"
left="3"
@@ -510,7 +515,7 @@
Roll Scale
</text>
<spinner
- bottom="244"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale3"
decimal_digits="2"
@@ -522,7 +527,7 @@
name="BuildAxisScale3"
width="56" />
<spinner
- bottom="244"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale3"
decimal_digits="2"
@@ -536,7 +541,7 @@
<text
type="string"
length="1"
- bottom="274"
+ bottom="282"
halign="right"
layout="topleft"
left="3"
@@ -545,7 +550,7 @@
X Dead Zone
</text>
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone1"
decimal_digits="2"
@@ -556,7 +561,7 @@
name="AvatarAxisDeadZone1"
width="56" />
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone1"
decimal_digits="2"
@@ -567,7 +572,7 @@
name="BuildAxisDeadZone1"
width="56" />
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone1"
decimal_digits="2"
@@ -580,7 +585,7 @@
<text
type="string"
length="1"
- bottom="294"
+ bottom="302"
halign="right"
layout="topleft"
left="3"
@@ -589,7 +594,7 @@
Y Dead Zone
</text>
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone2"
decimal_digits="2"
@@ -600,7 +605,7 @@
name="AvatarAxisDeadZone2"
width="56" />
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone2"
decimal_digits="2"
@@ -611,7 +616,7 @@
name="BuildAxisDeadZone2"
width="56" />
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone2"
decimal_digits="2"
@@ -624,7 +629,7 @@
<text
type="string"
length="1"
- bottom="314"
+ bottom="322"
halign="right"
layout="topleft"
left="3"
@@ -633,7 +638,7 @@
Z Dead Zone
</text>
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone0"
decimal_digits="2"
@@ -644,7 +649,7 @@
name="AvatarAxisDeadZone0"
width="56" />
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone0"
decimal_digits="2"
@@ -655,7 +660,7 @@
name="BuildAxisDeadZone0"
width="56" />
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone0"
decimal_digits="2"
@@ -668,7 +673,7 @@
<text
type="string"
length="1"
- bottom="334"
+ bottom="342"
halign="right"
layout="topleft"
left="2"
@@ -677,7 +682,7 @@
Pitch Dead Zone
</text>
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone4"
decimal_digits="2"
@@ -688,7 +693,7 @@
name="AvatarAxisDeadZone4"
width="56" />
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone4"
decimal_digits="2"
@@ -699,7 +704,7 @@
name="BuildAxisDeadZone4"
width="56" />
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone4"
decimal_digits="2"
@@ -712,7 +717,7 @@
<text
type="string"
length="1"
- bottom="354"
+ bottom="362"
halign="right"
layout="topleft"
left="3"
@@ -721,7 +726,7 @@
Yaw Dead Zone
</text>
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone5"
decimal_digits="2"
@@ -732,7 +737,7 @@
name="AvatarAxisDeadZone5"
width="56" />
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone5"
decimal_digits="2"
@@ -743,7 +748,7 @@
name="BuildAxisDeadZone5"
width="56" />
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone5"
decimal_digits="2"
@@ -756,7 +761,7 @@
<text
type="string"
length="1"
- bottom="374"
+ bottom="382"
halign="right"
layout="topleft"
left="3"
@@ -765,7 +770,7 @@
Roll Dead Zone
</text>
<spinner
- bottom="374"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone3"
decimal_digits="2"
@@ -776,7 +781,7 @@
name="BuildAxisDeadZone3"
width="56" />
<spinner
- bottom="374"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone3"
decimal_digits="2"
@@ -789,7 +794,7 @@
<text
type="string"
length="1"
- bottom="402"
+ bottom="410"
halign="right"
layout="topleft"
left="3"
@@ -810,7 +815,7 @@
min_val="1"
name="AvatarFeathering"
show_text="false"
- top="402"
+ top="410"
width="73" />
<slider
control_name="BuildFeathering"
@@ -845,7 +850,7 @@
<text
type="string"
length="1"
- bottom="430"
+ bottom="438"
halign="right"
layout="topleft"
left="3"
@@ -854,7 +859,7 @@
Zoom Scale
</text>
<spinner
- bottom="430"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale6"
decimal_digits="2"
@@ -868,7 +873,7 @@
<text
type="string"
length="1"
- bottom="450"
+ bottom="458"
halign="right"
layout="topleft"
left="3"
@@ -877,7 +882,7 @@
Zoom Dead Zone
</text>
<spinner
- bottom="450"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone6"
decimal_digits="2"
@@ -894,7 +899,7 @@
layout="topleft"
left="359"
name="SpaceNavigatorDefaults"
- top="429"
+ top="437"
width="200" />
<button
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/floater_load_pref_preset.xml b/indra/newview/skins/default/xui/en/floater_load_pref_preset.xml
index 5f2eb770e2..49c21f1ea7 100644
--- a/indra/newview/skins/default/xui/en/floater_load_pref_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_load_pref_preset.xml
@@ -4,7 +4,7 @@
height="130"
help_topic="floater_load_preset"
layout="topleft"
- name="Load Pref Preset"
+ name="load_pref_preset"
save_rect="true"
title="LOAD PREF PRESET"
width="300">
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
deleted file mode 100644
index 7802f65902..0000000000
--- a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="true"
- height="440"
- help_topic="floater_merchant_outbox"
- min_width="300"
- min_height="200"
- name="floater_merchant_outbox"
- save_rect="true"
- save_visibility="false"
- reuse_instance="true"
- title="MERCHANT OUTBOX"
- width="333">
- <string name="OutboxFolderCount0"></string>
- <string name="OutboxFolderCount1">1 folder</string>
- <string name="OutboxFolderCountN">[NUM] folders</string>
- <string name="OutboxImporting">Sending folders...</string>
- <string name="OutboxInitializing">Initializing...</string>
- <panel
- name="panel_1"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- label=""
- height="440"
- width="333">
- <panel
- name="panel_2"
- follows="all"
- left="10"
- bottom="370"
- width="313"
- top="0"
- bg_opaque_color="InventoryBackgroundColor">
- <panel
- name="outbox_inventory_placeholder_panel"
- follows="all"
- layout="topleft"
- top="0"
- left="0"
- width="308"
- height="370"
- bg_opaque_color="InventoryBackgroundColor">
- <text
- name="outbox_inventory_placeholder_title"
- type="string"
- follows="top|left|right"
- layout="topleft"
- top="10"
- left="0"
- width="308"
- height="25"
- wrap="true"
- halign="center"
- font="SansSerifBold">
- Loading...
- </text>
- <text
- name="outbox_inventory_placeholder_text"
- type="string"
- follows="top|left|right"
- layout="topleft"
- top="35"
- left="0"
- width="308"
- height="130"
- wrap="true"
- halign="left" />
- </panel>
- </panel>
- <panel
- name="panel_3"
- follows="bottom|left|right"
- left="10"
- bottom="435"
- width="313"
- top="370">
- <panel
- name="outbox_generic_drag_target"
- mouse_opaque="false"
- follows="all"
- top="5"
- left="5"
- width="303"
- height="25"
- background_visible="false"
- bg_alpha_color="EmphasisColor_35"
- border="true"
- bevel_style="in"
- visible="true">
- <text
- name="text_1"
- type="string"
- follows="all"
- layout="topleft"
- top="6"
- height="20"
- left="5"
- width="293"
- halign="center"
- font="SansSerifMedium"
- font_shadow="hard"
- valign="top">
- Drag items here to create folders
- </text>
- </panel>
- <text
- name="outbox_folder_count"
- type="string"
- follows="all"
- layout="topleft"
- top="40"
- left="5"
- width="150"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- font="SansSerif"/>
- <button
- label="Send to Marketplace"
- tool_tip="Push to my Marketplace Storefront"
- is_toggle="false"
- name="outbox_import_btn"
- follows="bottom|right"
- tab_stop="false"
- halign="center"
- top="37"
- left="160"
- height="25"
- width="150"
- enabled="false" />
- </panel>
- <layout_stack name="import_progress_indicator" orientation="vertical" left="0" height="440" top="0" width="333" follows="all" visible="false">
- <layout_panel />
- <layout_panel height="24" auto_resize="false">
- <layout_stack orientation="horizontal" left="0" height="24" top="0" width="333" follows="all">
- <layout_panel width="0" />
- <layout_panel width="24" auto_resize="false">
- <loading_indicator
- height="24"
- layout="topleft"
- left="0"
- top="0"
- width="24" />
- </layout_panel>
- <layout_panel width="0" />
- </layout_stack>
- </layout_panel>
- <layout_panel />
- </layout_stack>
- </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 5a86eb06fb..7f863756eb 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -2,15 +2,16 @@
<floater
can_close="true"
can_drag_on_left="false"
- can_minimize="false"
- can_resize="false"
- height="480"
- min_height="480"
+ can_minimize="true"
+ can_resize="true"
+ height="625"
+ min_height="625"
width="980"
min_width="980"
name="Model Preview"
title="UPLOAD MODEL"
- help_topic="upload_model" >
+ help_topic="upload_model"
+ legacy_header_height="25">
<string name="status_idle"></string>
<string name="status_parse_error">Error: Dae parsing issue - see log for details.</string>
@@ -33,19 +34,27 @@
<string name="mesh_status_missing_lod">Missing required level of detail.</string>
<string name="mesh_status_invalid_material_list">LOD materials are not a subset of reference model.</string>
<string name="phys_status_vertex_limit_exceeded">Some physical hulls exceed vertex limitations.</string>
+ <string name="phys_status_degenerate_triangles">The physics mesh too dense remove the small thin triangles (see preview)</string>
<string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" -->
<string name="decomposing">Analyzing...</string>
<string name="simplifying">Simplifying...</string>
<string name="tbd">TBD</string>
+
+ <!-- Warnings and info from model loader-->
+ <string name="TooManyJoint">Skinning disabled due to too many joints: [JOINTS], maximum: [MAX]</string>
+ <string name="UnrecognizedJoint">Rigged to unrecognized joint name [NAME]</string>
+ <string name="UnknownJoints">Skinning disabled due to [COUNT] unknown joints</string>
+ <string name="ModelLoaded">Model [MODEL_NAME] loaded</string>
+ <string name="IncompleteTC">Texture coordinates data is not complete.</string>
-<panel
- follows="top|left"
- height="455"
- layout="topleft"
- left="3"
- name="left_panel"
- top_pad="10"
- width="630">
+ <panel
+ follows="top|left"
+ height="595"
+ layout="topleft"
+ left="3"
+ name="left_panel"
+ top_pad="25"
+ width="635">
<panel
follows="all"
height="50"
@@ -76,12 +85,16 @@
</panel>
<tab_container
follows="top|left"
- top_pad="15"
+ top_pad="10"
left="0"
- height="300"
+ height="330"
width="635"
name="import_tab"
- tab_position="top">
+ tab_position="top"
+ enable_tabs_flashing="true"
+ tabs_flashing_color="MenuItemFlashBgColor">
+ <last_tab
+ tab_top_image_flash="TabTop_Right_Flashing"/> <!-- for log tab -->
<!-- LOD PANEL -->
<panel
help_topic="upload_model_lod"
@@ -92,12 +105,12 @@
<view_border
bevel_style="none"
follows="top|left"
- height="275"
+ height="306"
layout="topleft"
left="3"
name="lod_tab_border"
top_pad="0"
- width="629" />
+ width="628" />
<text
follows="left|top"
height="18"
@@ -688,7 +701,7 @@
left="10"
name="lod_tab_border"
top_pad="20"
- width="605" />
+ width="614" />
<check_box
follows="top|left"
height="15"
@@ -730,12 +743,12 @@
<view_border
bevel_style="none"
follows="top|left"
- height="275"
+ height="306"
layout="topleft"
left="3"
name="physics_tab_border"
top_pad="0"
- width="619"/>
+ width="628"/>
<panel
bg_alpha_color="0 0 0 0"
bg_opaque_color="0 0 0 0.3"
@@ -755,8 +768,9 @@
name="first_step_name"
text_color="White"
top_pad="0"
- width="210">
- Step 1: Level of Detail
+ width="210"
+ valign="center">
+ Step 1: Pick a physics model :
</text>
<combo_box
follows="left|top"
@@ -798,7 +812,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -807,7 +821,7 @@
follows="top|left"
left="18"
name="physics analysis"
- top_pad="15"
+ top_pad="10"
visible="true"
width="589">
<text
@@ -819,7 +833,7 @@
name="method_label"
text_color="White"
top_pad="0">
- Step 2: Analyze
+ Step 2: Convert to hulls (optional)
</text>
<text
follows="top|left"
@@ -905,7 +919,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -914,7 +928,7 @@
height="66"
left="18"
name="physics simplification"
- top_pad="15"
+ top_pad="10"
width="589">
<text
text_color="White"
@@ -1013,7 +1027,7 @@
layout="topleft"
left="18"
name="physics_tab_border"
- top_pad="15"
+ top_pad="10"
width="589"/>
<panel
bg_alpha_color="0 0 0 0"
@@ -1075,10 +1089,9 @@
follows="left|top"
height="19"
layout="topleft"
- left_pad="5"
- top_delta="0"
+ top_pad="5"
name="physics message"
- width="270">
+ width="589">
<icon
follows="left|top"
height="16"
@@ -1093,7 +1106,7 @@
layout="topleft"
left_pad="2"
name="physics_status_message_text"
- width="252"
+ width="573"
top_delta="3"/>
</panel>
</panel>
@@ -1105,12 +1118,12 @@
<view_border
bevel_style="none"
follows="top|left"
- height="275"
+ height="306"
layout="topleft"
left="3"
name="border"
top_pad="0"
- width="619"/>
+ width="628"/>
<text
follows="top|left"
height="16"
@@ -1157,75 +1170,211 @@
label_text.text_color="White"
left="20"
top_pad="20"/>
- <view_border
- bevel_style="none"
- follows="top|left"
- height="0"
- layout="topleft"
- name="border"
- top_pad="20"
- width="579"/>
- <text
- follows="top|left"
- height="15"
- left="20"
- name="include_label"
- text_color="White"
- top_pad="20"
- width="150">
- For avatar models only:
- </text>
- <check_box
- follows="top|left"
- height="15"
- label="Include skin weight"
- label_text.text_color="White"
- name="upload_skin"
- top_pad="15"/>
- <check_box
- follows="top|left"
- height="15"
- label="Include joint positions"
- label_text.text_color="White"
- name="upload_joints"
- top_pad="15"/>
- <check_box
- follows="top|left"
- height="15"
- label="Lock scale if joint position defined"
- label_text.text_color="White"
- name="lock_scale_if_joint_position"
- top_pad="15"/>
- <text
- follows="top|left"
- height="15"
- layout="topleft"
- left="220"
- name="pelvis_offset_label"
- text_color="White"
- top="134"
- width="200">
- Z offset (raise or lower avatar):
- </text>
- <spinner
- follows="top|left"
- height="20"
- min_val="-3.00"
- max_val="3.0"
- name="pelvis_offset"
- top_pad="10"
- value="0.0"
- width="80"/>
</panel>
+ <panel
+ label="Overrides"
+ layout="topleft"
+ name="rigging_panel"
+ title="Rigging">
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="306"
+ layout="topleft"
+ left="3"
+ name="avatar_tab_border"
+ top_pad="0"
+ width="628" />
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Include skin weight"
+ label_text.text_color="White"
+ name="upload_skin"
+ top="8"
+ left="20"/>
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Include joint positions"
+ label_text.text_color="White"
+ name="upload_joints"
+ left_delta="0"
+ top_pad="7"/>
+ <check_box
+ follows="top|left"
+ height="15"
+ label="Lock scale if joint position defined"
+ label_text.text_color="White"
+ name="lock_scale_if_joint_position"
+ top_pad="7"/>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="220"
+ name="pelvis_offset_label"
+ text_color="White"
+ top="8"
+ width="200">
+ Z offset (raise or lower avatar):
+ </text>
+ <spinner
+ follows="top|left"
+ height="20"
+ min_val="-3.00"
+ max_val="3.0"
+ name="pelvis_offset"
+ top_pad="10"
+ value="0.0"
+ width="80"/>
+ <text
+ follows="top|left"
+ height="17"
+ left="425"
+ name="skin_too_many_joints"
+ text_color="Orange"
+ top="7"
+ width="195"
+ word_wrap="true">
+ Too many skinned joints
+ </text>
+ <text
+ follows="top|left"
+ height="32"
+ left="425"
+ name="skin_unknown_joint"
+ text_color="Orange"
+ top="8"
+ width="195"
+ word_wrap="true">
+ Model has an unknown joint(s)
+ </text>
+ <text
+ layout="topleft"
+ follows="top|left"
+ height="15"
+ left="20"
+ name="joints_descr"
+ top="73"
+ width="150">
+ Joints:
+ </text>
+ <scroll_list
+ layout="topleft"
+ follows="top|left"
+ name="joints_list"
+ column_padding="0"
+ draw_heading="false"
+ draw_stripes="false"
+ commit_on_selection_change="true"
+ heading_height="23"
+ height="199"
+ left_delta="0"
+ top_pad="0"
+ width="200"/>
+ <text
+ layout="topleft"
+ follows="top|left"
+ height="15"
+ left_delta="0"
+ name="conflicts_description"
+ top_pad="2"
+ width="200">
+ [CONFLICTS] conflicts in [JOINTS_COUNT] joints
+ </text>
+ <text
+ layout="topleft"
+ follows="top|left"
+ height="15"
+ left_pad="5"
+ name="pos_overrides_descr"
+ top="73"
+ width="300">
+ Position overrides for joint '[JOINT]':
+ </text>
+ <scroll_list
+ layout="topleft"
+ follows="top|left"
+ name="pos_overrides_list"
+ column_padding="0"
+ draw_heading="true"
+ draw_stripes="false"
+ heading_height="23"
+ height="100"
+ left_delta="0"
+ top_pad="0"
+ width="385">
+ <scroll_list.columns
+ label="Model"
+ name="model_name"
+ relative_width="0.49" />
+ <scroll_list.columns
+ label="X"
+ name="axis_x"
+ relative_width="0.17" />
+ <scroll_list.columns
+ label="Y"
+ name="axis_y"
+ relative_width="0.17" />
+ <scroll_list.columns
+ label="Z"
+ name="axis_z"
+ relative_width="0.17" />
+ </scroll_list>
+ </panel>
+ <panel
+ label="Log"
+ layout="topleft"
+ name="logs_panel"
+ title="Log">
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="289"
+ layout="topleft"
+ left="3"
+ name="log_tab_border"
+ top_pad="0"
+ width="628" />
+ <text_editor
+ type="string"
+ length="1"
+ embedded_items="false"
+ follows="top|left"
+ font="SansSerif"
+ ignore_tab="false"
+ layout="topleft"
+ height="289"
+ left="4"
+ top="0"
+ right="-1"
+ max_length="65536"
+ name="log_text"
+ parse_urls="true"
+ spellcheck="false"
+ read_only="true"
+ word_wrap="true">
+ </text_editor>
+ <check_box
+ control_name="ImporterDebug"
+ follows="top|left"
+ top_pad="9"
+ left="6"
+ width="70"
+ label="Enable detailed logging (can be very slow)"
+ name="verbose_logging"/>
+ </panel>
</tab_container>
<panel
- follows="top|left"
- height="80"
- layout="top|left"
- left="0"
+ follows="top|left|bottom"
+ layout="topleft"
+ height="195"
+ left="4"
+ border="true"
name="weights_and_warning_panel"
top_pad="3"
- width="625">
+ width="629">
<button
follows="top|left"
label="Calculate weights &amp; fee"
@@ -1265,10 +1414,10 @@
label_color="White"
layout="topleft"
name="reset_btn"
- right="-2"
+ right="-5"
top="3"
height="20"
- width="275"/>
+ width="265"/>
<!-- ========== WEIGHTS ==========-->
<text
follows="top|left"
@@ -1287,7 +1436,7 @@
left_pad="0"
name="prim_weight"
top_delta="0"
- width="120"
+ width="130"
word_wrap="true">
Land impact: [EQ]
</text>
@@ -1297,7 +1446,7 @@
left_pad="0"
name="download_weight"
top_delta="0"
- width="100"
+ width="130"
word_wrap="true">
Download: [ST]
</text>
@@ -1307,7 +1456,7 @@
layout="topleft"
left_pad="0"
name="physics_weight"
- width="90"
+ width="130"
word_wrap="true">
Physics: [PH]
</text>
@@ -1317,19 +1466,150 @@
layout="topleft"
left_pad="0"
name="server_weight"
- width="83"
+ width="130"
word_wrap="true">
Server: [SIM]
</text>
- <!-- ========== NOTE MESSAGE ========== -->
+ <!-- =========== Cost breakdown ======== -->
+ <panel
+ border="true"
+ top_pad="5"
+ layout="topleft"
+ left="6"
+ name="price_breakdown_panel"
+ width="120"
+ height="100">
+ <text
+ layout="topleft"
+ left="3">
+ Price Breakdown
+ </text>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_border"
+ top_pad="5"
+ width="110"/>
+ <text
+ height="80"
+ top_pad="5"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_labels"
+ width="70"
+ word_wrap="false">
+Download:
+Physics:
+Instances:
+Textures:
+Model:
+ </text>
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ halign="right"
+ left_pad="0"
+ name="price_breakdown"
+ width="40"
+ word_wrap="false">
+[STREAMING]
+[PHYSICS]
+[INSTANCES]
+[TEXTURES]
+[MODEL]
+ </text>
+ </panel>
+ <!--
+ Streaming breakdown numbers are available but not fully understood
+ uncommenting the following sections will display the numbers for debugging purposes
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left="130"
+ name="streaming_breakdown_labels"
+ width="65"
+ word_wrap="true">
+Streaming/Download:
+High:
+Medium:
+Low:
+Lowest:
+ </text>
<text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="streaming_breakdown"
+ width="95"
+ word_wrap="true">
+[STR_TOTAL]
+[STR_HIGH]
+[STR_MED]
+[STR_LOW]
+[STR_LOWEST]
+ </text>-->
+ <panel
+ border="true"
+ layout="topleft"
+ left_pad="265"
+ name="physics_costs_panel"
+ width="120"
+ height="100">
+ <text
+ layout="topleft"
+ left="3">
+ Physics Costs
+ </text>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="3"
+ name="price_breakdown_border"
+ top_pad="5"
+ width="110"/>
+ <text
+ height="80"
+ top_pad="5"
+ layout="topleft"
+ left="5"
+ name="physics_breakdown_labels"
+ width="65">
+Base Hull:
+Mesh:
+Analysed:
+ </text>
+ <text
+ height="80"
+ top_delta="0"
+ layout="topleft"
+ left_pad="0"
+ name="physics_breakdown"
+ width="40"
+ halign="right"
+ word_wrap="false"
+ visible="true">
+[PCH]
+[PM]
+[PHU]
+ </text>-->
+ </panel>
+ <!-- ========== NOTE MESSAGE ========== -->
+ <text
font="SansSerif"
layout="topleft"
left="6"
name="warning_title"
- top_pad="10"
+ top_pad="5"
text_color="DrYellow"
- visible="false"
+ visible="true"
width="40">
NOTE:
</text>
@@ -1340,44 +1620,51 @@
left_pad="1"
name="warning_message"
parse_urls="true"
- top_delta="2"
+ top_delta="1"
wrap="true"
width="462"
- visible="false">
+ visible="true">
You dont have rights to upload mesh models. [[VURL] Find out how] to get certified.
+ </text>
+ <text
+ text_color="Yellow"
+ layout="topleft"
+ top_pad="-2"
+ left="6"
+ name="status">
+[STATUS]
</text>
- <text text_color="Yellow" layout="topleft" top_delta="20" left="6" name="status">[STATUS]</text>
-
</panel>
-</panel>
-
-<text
- follows="left|top"
- layout="topleft"
- left="640"
- name="lod_label"
- text_color="White"
- top="13"
- height="15"
- width="290">
- Preview:
- </text>
-<panel
- border="true"
- bevel_style="none"
- follows="top|left"
- name="preview_panel"
- top_pad="4"
- width="290"
- height="290"/>
-
-<panel
- follows="all"
- height="130"
- layout="topleft"
- name="right_panel"
- top_pad="5"
- width="340">
+ </panel>
+
+ <text
+ follows="left|top"
+ layout="topleft"
+ left="640"
+ name="lod_label"
+ text_color="White"
+ top="29"
+ height="15"
+ width="290">
+ Preview:
+ </text>
+ <panel
+ follows="all"
+ layout="topleft"
+ border="true"
+ bevel_style="none"
+ name="preview_panel"
+ top_pad="4"
+ width="325"
+ height="408"/>
+ <panel
+ follows="right|bottom"
+ can_resize="false"
+ height="140"
+ layout="topleft"
+ name="right_panel"
+ top_pad="5"
+ width="340">
<combo_box
top_pad="3"
follows="left|top"
@@ -1386,10 +1673,10 @@
name="preview_lod_combo"
width="150"
tool_tip="LOD to view in preview render">
- <combo_item name="high"> High </combo_item>
- <combo_item name="medium"> Medium </combo_item>
- <combo_item name="low"> Low </combo_item>
- <combo_item name="lowest"> Lowest </combo_item>
+ <combo_item name="high"> High </combo_item>
+ <combo_item name="medium"> Medium </combo_item>
+ <combo_item name="low"> Low </combo_item>
+ <combo_item name="lowest"> Lowest </combo_item>
</combo_box>
<text
follows="top|left"
@@ -1436,11 +1723,21 @@
</check_box>
<check_box
follows="top|left"
+ label="Joint position overrides"
+ label_text.text_color="White"
+ word_wrap="down"
+ width="130"
+ layout="topleft"
+ name="show_joint_overrides"
+ top_pad="8">
+ </check_box>
+ <check_box
+ follows="top|left"
label="Joints"
label_text.text_color="White"
layout="topleft"
name="show_joint_positions"
- top_pad="8">
+ top_pad="17">
</check_box>
<text
follows="top|left"
@@ -1460,5 +1757,5 @@
max_val="3.0"
height="20"
width="150"/>
-</panel>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
index fdea7a821a..35ad87ceb0 100644
--- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
@@ -11,7 +11,7 @@
save_rect="true"
single_instance="true"
reuse_instance="true"
- title="APPEARANCE"
+ title="AVATAR"
min_height="440"
min_width="333"
width="333">
diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml
new file mode 100644
index 0000000000..6aff387dcb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ positioning="cascading"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ legacy_header_height="18"
+ can_resize="true"
+ height="465"
+ name="my_environments"
+ help_topic="my_environments"
+ title="MY ENVIRONMENTS"
+ background_visible="true"
+ label="Places"
+ layout="topleft"
+ min_height="350"
+ min_width="265"
+ width="313">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="20"
+ right="-5"
+ bottom="-5"
+ orientation="vertical">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="false"
+ tab_group="1"
+ height="54"
+ name="filter_panel"
+ label="Filters"
+ font="SansSerifBold">
+ <icon
+ height="16"
+ image_name="Inv_SettingsDay"
+ layout="topleft"
+ mouse_opaque="true"
+ name="icon_settingsdays"
+ left="4"
+ width="16" />
+ <check_box
+ height="16"
+ label="Days"
+ layout="topleft"
+ left_pad="2"
+ name="chk_days"
+ top_delta="0"
+ width="60" />
+ <icon
+ height="16"
+ image_name="Inv_SettingsSky"
+ layout="topleft"
+ mouse_opaque="true"
+ name="icon_settingsskies"
+ left_pad="10"
+ width="16" />
+ <check_box
+ height="16"
+ label="Skies"
+ layout="topleft"
+ left_pad="2"
+ name="chk_skies"
+ top_delta="0"
+ width="60" />
+ <icon
+ height="16"
+ image_name="Inv_SettingsWater"
+ layout="topleft"
+ mouse_opaque="true"
+ name="icon_settingswater"
+ left_pad="10"
+ width="16" />
+ <check_box
+ height="16"
+ label="Water"
+ layout="topleft"
+ left_pad="2"
+ name="chk_water"
+ top_delta="0"
+ width="60" />
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ label="Filter Environments"
+ layout="topleft"
+ left="4"
+ name="flt_search"
+ top_pad="6"
+ right="-4" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ user_resize="true"
+ tab_group="1"
+ name="list_panel"
+ label="Environments"
+ font="SansSerifBold">
+ <panel
+ name="pnl_inv_wrap"
+ label="pnl_inv_wrap"
+ follows="all"
+ layout="topleft"
+ left="2"
+ top="2"
+ right="-2"
+ bottom="-2"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ border="true">
+ <asset_filtered_inv_panel
+ left="0"
+ top="0"
+ right="-1"
+ bottom="-1"
+ allow_multi_select="false"
+ follows="all"
+ layout="topleft"
+ name="pnl_settings"
+ filter_asset_type="settings"/>
+ </panel>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ user_resize="false"
+ tab_group="1"
+ height="15">
+ <check_box
+ follows="left|bottom"
+ height="14"
+ initial_value="false"
+ label="Show All Folders"
+ layout="topleft"
+ name="chk_showfolders"
+ top="2"
+ left_delta="-1"
+ width="200" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ tab_group="1"
+ height="31"
+ name="pnl_control"
+ font="SansSerifBold">
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ top_pad="1"
+ follows="top|left|right"
+ height="30"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="pnl_bottom">
+ <menu_button
+ follows="bottom|left"
+ height="18"
+ image_disabled="OptionsMenu_Disabled"
+ image_selected="OptionsMenu_Press"
+ image_unselected="OptionsMenu_Off"
+ layout="topleft"
+ left="10"
+ menu_filename="menu_settings_gear.xml"
+ name="btn_gear"
+ top="5"
+ tool_tip="More options"
+ width="18" />
+ <menu_button
+ follows="bottom|left"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="AddItem_Press"
+ image_unselected="AddItem_Off"
+ image_disabled="AddItem_Disabled"
+ layout="topleft"
+ left_pad="5"
+ menu_filename="menu_settings_add.xml"
+ name="btn_newsettings"
+ tool_tip="Make new setting"
+ top_delta="0"
+ width="18" />
+ <button
+ follows="bottom|right"
+ font="SansSerifBigBold"
+ height="18"
+ image_selected="TrashItem_Press"
+ image_unselected="TrashItem_Off"
+ image_disabled="TrashItem_Disabled"
+ layout="topleft"
+ name="btn_del"
+ right="-5"
+ tool_tip="Remove selected item"
+ top_delta="0"
+ width="18" />
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
index 3b0b6723c7..ee6defce9d 100644
--- a/indra/newview/skins/default/xui/en/floater_my_scripts.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
@@ -7,7 +7,7 @@
layout="topleft"
name="myscripts"
save_rect="true"
- title="My Scripts"
+ title="ATTACHMENT SCRIPTS"
min_width="620"
width="620">
<panel
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 701233ba4a..0cc0ca1ce4 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -31,5 +31,11 @@
filename="panel_group_info_sidetray.xml"
label="Group Profile"
font="SansSerifBold"/>
+ <panel
+ class="panel_group_creation_sidetray"
+ name="panel_group_creation_sidetray"
+ filename="panel_group_creation_sidetray.xml"
+ label="Create Group"
+ font="SansSerifBold"/>
</panel_container>
</floater>
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 1c3af49bfe..49dc719a24 100644
--- a/indra/newview/skins/default/xui/en/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -488,6 +488,67 @@
left_pad="0"
top_delta="0"
width="100" />
+ <text
+ name="label_13"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Environment settings are created"
+ width="100">
+ Settings
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Settings"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ height="16"
+ layout="topleft"
+ name="env_settings_c"
+ left_pad="45"
+ top_delta="0"
+ value="true"
+ enabled="false"
+ width="100">
+ </check_box>
+ <check_box
+ control_name="SettingsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="env_settings_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="SettingsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="env_settings_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled="false"
+ height="16"
+ layout="topleft"
+ name="env_settings_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ enabled="false"
+ height="16"
+ layout="topleft"
+ name="env_settings_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
</panel>
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_pick_track.xml b/indra/newview/skins/default/xui/en/floater_pick_track.xml
new file mode 100644
index 0000000000..d8a9877be2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pick_track.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<floater
+ legacy_header_height="0"
+ can_minimize="false"
+ can_resize="true"
+ height="140"
+ layout="topleft"
+ min_height="140"
+ min_width="225"
+ name="track picker"
+ help_topic="track_picker"
+ title="PICK: TRACK"
+ width="225">
+ <layout_stack name="adjuster"
+ follows="all"
+ animate="false"
+ top="0"
+ left="6"
+ right="-6"
+ bottom="-10"
+ orientation="vertical">
+ <layout_panel name="pnl_desc"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="11"
+ min_height="10"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="5"
+ name="select_description"
+ mouse_opaque="false"
+ top="0"
+ width="300">
+ Select source sky:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks"
+ border="false"
+ auto_resize="true"
+ user_resize="false"
+ height="29"
+ min_height="29"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <radio_group
+ follows="all"
+ height="60"
+ layout="topleft"
+ top="0"
+ left="3"
+ right="-3"
+ bottom="-3"
+ name="track_selection"
+ width="100">
+ <radio_item
+ height="20"
+ label="Sky4 [ALT]"
+ layout="topleft"
+ left="0"
+ name="radio_sky4"
+ value="4"
+ top="0"
+ width="90" />
+ <radio_item
+ height="20"
+ label="Sky3 [ALT]"
+ layout="topleft"
+ left="0"
+ name="radio_sky3"
+ value="3"
+ top_delta="20"
+ width="90" />
+ <radio_item
+ height="20"
+ label="Sky2 [ALT]"
+ layout="topleft"
+ left="0"
+ name="radio_sky2"
+ value="2"
+ top_delta="20"
+ width="90" />
+ <radio_item
+ height="20"
+ label="Ground"
+ layout="topleft"
+ left="0"
+ name="radio_sky1"
+ value="1"
+ top_delta="20"
+ width="90" />
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ min_height="29">
+ <button
+ follows="top|left"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="2"
+ top="2"
+ name="btn_select"
+ width="100" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_delta="110"
+ top_delta="0"
+ name="btn_cancel"
+ width="100" />
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 0e62d50072..ee730dcb01 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -169,6 +169,13 @@ https://accounts.secondlife.com/change_email/
layout="topleft"
help_topic="preferences_uploads_tab"
name="uploads" />
+ <panel
+ class="panel_preference_controls"
+ filename="panel_preferences_controls.xml"
+ label="Controls"
+ layout="topleft"
+ help_topic="preferences_controls_tab"
+ name="controls" />
</tab_container>
</floater>
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 bec484a5ea..3cc99b28c9 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
@@ -596,7 +596,10 @@
left="420"
name="TransparentWater"
top_delta="16"
- width="300" />
+ width="300">
+ <check_box.commit_callback
+ function="Pref.RenderOptionUpdate" />
+ </check_box>
<check_box
control_name="RenderObjectBump"
@@ -609,7 +612,7 @@
top_delta="16"
width="300">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
@@ -623,6 +626,7 @@
top_delta="16"
width="300" />
+ <!-- SL-12594, basic shaders always enabled, no fixed-function GL
<check_box
control_name="VertexShaderEnable"
height="16"
@@ -637,7 +641,8 @@
<check_box.commit_callback
function="Pref.VertexShaderEnable" />
</check_box>
-
+ -->
+
<slider
control_name="RenderTerrainDetail"
follows="left|top"
@@ -683,7 +688,7 @@
top_delta="16"
width="280">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
@@ -719,6 +724,14 @@
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"/>
@@ -751,7 +764,7 @@
top_delta="16"
width="280">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<slider
@@ -800,7 +813,7 @@
top_delta="16"
width="260">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
@@ -814,7 +827,7 @@
top_delta="16"
width="240">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
@@ -828,8 +841,24 @@
top_delta="16"
width="240">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ 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"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_view_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_view_advanced.xml
new file mode 100644
index 0000000000..4c3c7e4930
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_preferences_view_advanced.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="190"
+ layout="topleft"
+ name="floaterpreferencesviewadvanced"
+ help_topic="floaterviewadvanced"
+ title="CAMERA POSITION"
+ save_rect="true"
+ width="280">
+
+ <text
+ follows="top|left|right"
+ name="camera_offset_lbl"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="10"
+ width="100">
+ Camera offset:
+ </text>
+
+ <spinner
+ height="20"
+ label="X"
+ label_width="12"
+ follows="top|left"
+ left="10"
+ name="camera_x"
+ top_pad="5"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <spinner
+ height="20"
+ label="Y"
+ label_width="12"
+ follows="top|left"
+ name="camera_y"
+ left_pad="20"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <spinner
+ height="20"
+ label="Z"
+ label_width="12"
+ follows="top|left"
+ name="camera_z"
+ left_pad="20"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <text
+ follows="top|left|right"
+ name="focus_offset_lbl"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="20"
+ width="100">
+ Focus offset:
+ </text>
+
+ <spinner
+ height="20"
+ label="X"
+ label_width="12"
+ follows="top|left"
+ left="10"
+ name="focus_x"
+ top_pad="5"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <spinner
+ height="20"
+ label="Y"
+ label_width="12"
+ follows="top|left"
+ name="focus_y"
+ left_pad="20"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <spinner
+ height="20"
+ label="Z"
+ label_width="12"
+ follows="top|left"
+ name="focus_z"
+ left_pad="20"
+ min_val="-1e+007"
+ max_val="1e+007"
+ width="70">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+ <text
+ follows="top|left|right"
+ name="offset_scale_lbl"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="20"
+ width="140">
+ Camera offset scale:
+ </text>
+
+ <slider
+ control_name="CameraOffsetScale"
+ follows="top|left|right"
+ height="16"
+ top_pad="5"
+ increment="0.1"
+ min_val="-3"
+ max_val="5"
+ show_text="false"
+ layout="topleft"
+ left="3"
+ name="offset_scale_sld"
+ width="196" />
+ <spinner
+ control_name="CameraOffsetScale"
+ height="20"
+ follows="top|left|right"
+ left_pad="5"
+ name="offset_scale_ctrl"
+ min_val="-3"
+ max_val="5"
+ width="58">
+ <spinner.commit_callback
+ function="CommitSettings" />
+ </spinner>
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_trash.xml b/indra/newview/skins/default/xui/en/floater_preview_trash.xml
index 9e50e89ac9..3fa71e7bfe 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_trash.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_trash.xml
@@ -14,7 +14,7 @@
reuse_instance="true"
can_minimize="false">
<inventory_panel
- name="inventory_outbox"
+ name="inventory_trash"
start_folder.name="Trash"
show_empty_message="false"
start_folder.type="trash"
diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
index 322e34272c..84e0b489d0 100644
--- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
@@ -6,6 +6,7 @@
layout="topleft"
name="publish_classified"
title="Publishing Classified"
+ help_topic="profile_edit_classified"
width="320">
<text
top="20"
diff --git a/indra/newview/skins/default/xui/en/floater_save_camera_preset.xml b/indra/newview/skins/default/xui/en/floater_save_camera_preset.xml
new file mode 100644
index 0000000000..54fdb6d167
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_save_camera_preset.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+ legacy_header_height="18"
+ height="185"
+ help_topic="floater_save_preset"
+ layout="topleft"
+ name="save_camera_preset"
+ save_rect="true"
+ title="Save Camera Preset"
+ width="280">
+
+ <string name="btn_label_save">Save</string>
+ <string name="btn_label_replace">Replace</string>
+ <radio_group
+ height="85"
+ layout="topleft"
+ left="20"
+ top="15"
+ width="150"
+ name="radio_save_preset">
+ <radio_item
+ label="Save as a new preset"
+ name="new_preset"
+ top="10"
+ layout="topleft"
+ height="16"
+ value="0"/>
+ <radio_item
+ label="Replace a preset"
+ name="replace_preset"
+ layout="topleft"
+ top="70"
+ height="16"
+ value="1"/>
+ </radio_group>
+ <line_editor
+ commit_on_focus_lost = "true"
+ follows="top|left"
+ height="23"
+ layout="topleft"
+ left="41"
+ name="preset_txt_editor"
+ width="200"
+ top="45"/>
+ <button
+ follows="top|left"
+ height="25"
+ label="Save"
+ layout="topleft"
+ top="145"
+ left="25"
+ name="save"
+ width="110"/>
+ <button
+ follows="bottom|right"
+ height="25"
+ label="Cancel"
+ layout="topleft"
+ left_pad="20"
+ name="cancel"
+ width="110"/>
+<!-- *HACK to correctly draw drop-down list over the buttons-->
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="41"
+ name="preset_combo"
+ top_delta="-40"
+ width="200"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml b/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml
index 7dee28eff3..62260274f5 100644
--- a/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_save_pref_preset.xml
@@ -4,14 +4,11 @@
height="145"
help_topic="floater_save_preset"
layout="topleft"
- name="Save Pref Preset"
+ name="save_pref_preset"
save_rect="true"
- title="SAVE PREF PRESET"
+ title="Save Graphic Preset"
width="300">
- <string name="title_graphic">Save Graphic Preset</string>
- <string name="title_camera">Save Camera Preset</string>
-
<text
follows="top|left|right"
height="32"
diff --git a/indra/newview/skins/default/xui/en/floater_script_debug.xml b/indra/newview/skins/default/xui/en/floater_script_debug.xml
index cd88048d6b..6c49cfa1a8 100644
--- a/indra/newview/skins/default/xui/en/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_debug.xml
@@ -17,5 +17,6 @@
name="Preview Tabs"
tab_position="bottom"
top="16"
- width="448" />
+ width="448"
+ enable_tabs_flashing="true"/>
</multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml
index 4e89df5a73..48d9eee4cd 100644
--- a/indra/newview/skins/default/xui/en/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/en/floater_select_key.xml
@@ -4,10 +4,27 @@
border="false"
can_close="false"
can_minimize="false"
- height="90"
+ height="116"
layout="topleft"
name="modal container"
- width="240">
+ width="272">
+ <floater.string
+ name="keyboard">
+ Keyboard
+ </floater.string>
+ <floater.string
+ name="mouse">
+ Mouse Buttons
+ </floater.string>
+ <floater.string
+ name="basic_description">
+Press a key to set your trigger.
+Allowed input: [INPUT].
+ </floater.string>
+ <floater.string
+ name="reserved_by_menu">
+Combination [KEYSTR] is reserved by menu.
+ </floater.string>
<text
type="string"
halign="center"
@@ -16,19 +33,47 @@
height="30"
layout="topleft"
left="30"
- name="Save item as:"
+ name="descritption"
top="25"
word_wrap="true"
- width="180">
- Press a key to set your Speak button trigger.
+ width="212">
+Press a key to set your trigger.
+Allowed input: [INPUT].
</text>
+ <check_box
+ follows="top|left"
+ height="20"
+ initial_value="false"
+ label="Apply to all"
+ layout="topleft"
+ left="90"
+ name="apply_all"
+ tool_tip="Viewer uses different control combinations depending on what you are doing in world, setting this will apply your change to all combinations"
+ top_pad="8"
+ width="160" />
+
+ <button
+ height="23"
+ label="Set Empty"
+ layout="topleft"
+ left="8"
+ name="SetEmpty"
+ top_pad="6"
+ width="80" />
+ <button
+ height="23"
+ label="Default"
+ layout="topleft"
+ left_pad="8"
+ name="Default"
+ top_delta="0"
+ width="80" />
<button
height="23"
label="Cancel"
- label_selected="Cancel"
layout="topleft"
- right="-10"
+ left_pad="8"
name="Cancel"
- top_pad="8"
- width="100" />
+ top_delta="0"
+ width="80" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_settings_picker.xml b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
new file mode 100644
index 0000000000..3a26c3b547
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ can_resize="true"
+ height="330"
+ layout="topleft"
+ min_height="330"
+ min_width="225"
+ name="settings picker"
+ help_topic="settings_picker"
+ title="PICK: SETTINGS"
+ width="225">
+
+ <!-- top static -->
+ <floater.string
+ name="pick title">
+ Pick:
+ </floater.string>
+ <floater.string
+ name="pick_track">
+ SELECT TRACK
+ </floater.string>
+ <floater.string
+ name="pick_settings">
+ SELECT SETTINGS
+ </floater.string>
+
+ <floater.string
+ name="track_water">
+ Water
+ </floater.string>
+ <floater.string
+ name="track_ground">
+ Ground
+ </floater.string>
+ <floater.string
+ name="track_sky">
+ Sky[NUM]
+ </floater.string>
+
+ <layout_stack name="test_stack"
+ follows="all"
+ animate="false"
+ top="20"
+ left="6"
+ right="-6"
+ bottom="-10"
+ orientation="vertical">
+ <layout_panel name="inv_list"
+ border="false"
+ auto_resize="true"
+ user_resize="false"
+ height="29"
+ min_height="29"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ label="Filter Settings"
+ layout="topleft"
+ left="4"
+ name="flt_inventory_search"
+ top="4"
+ right="-2" />
+ <panel
+ name="pnl_inv_wrap"
+ follows="all"
+ layout="topleft"
+ left="2"
+ top="28"
+ right="-2"
+ bottom="-2"
+ background_visible="true"
+ bg_alpha_color="DkGray2">
+ <asset_filtered_inv_panel
+ allow_multi_select="false"
+ allow_drag="false"
+ accepts_drag_and_drop="false"
+ suppress_folder_menu="true"
+ bg_visible="true"
+ bg_alpha_color="DkGray2"
+ border="false"
+ follows="all"
+ layout="topleft"
+ left_delta="0"
+ name="pnl_inventory"
+ top="1"
+ right="-4"
+ bottom="-1"
+ filter_asset_type="settings" />
+ </panel>
+ </layout_panel>
+ <layout_panel name="pnl_combo"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ visible="true"
+ height="29"
+ bg_alpha_color="blue"
+ background_visible="false">
+ <combo_box
+ allow_text_entry="false"
+ follows="left|top"
+ height="23"
+ left="10"
+ max_chars="100"
+ mouse_opaque="true"
+ name="track_selection"
+ enabled="false"
+ top="1"
+ width="190"/>
+ </layout_panel>
+ <layout_panel name="temp"
+ border="false"
+ auto_resize="false"
+ user_resize="false"
+ height="29"
+ min_height="29">
+ <button
+ follows="top|left"
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="2"
+ top="2"
+ name="btn_select"
+ width="100" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_delta="110"
+ top_delta="0"
+ name="btn_cancel"
+ width="100" />
+ </layout_panel>
+ </layout_stack>
+
+ <!-- middle: inventory mode -->
+ <!--
+
+
+-->
+ <!-- bottom static -->
+ <!--
+ -->
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sound_preview.xml b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
index af791466b6..3889b975a9 100644
--- a/indra/newview/skins/default/xui/en/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="190"
+ height="180"
layout="topleft"
name="Sound Preview"
help_topic="sound_preview"
@@ -60,9 +60,9 @@
height="22"
label="Upload (L$[AMOUNT])"
layout="topleft"
- left="45"
+ left="35"
name="ok_btn"
- top_pad="60"
+ top_pad="15"
width="150" />
<button
follows="right|bottom"
@@ -73,4 +73,17 @@
name="cancel_btn"
left_pad="5"
width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="35"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ skip_link_underline="true"
+ name="info_text"
+ word_wrap="true"
+ top_pad="10"
+ width="270"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
index a04050e7eb..a3ed22f422 100644
--- a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
@@ -1,226 +1,226 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- can_resize="true"
- can_close="true"
- bevel_style="in"
- height="300"
- layout="topleft"
- min_height="40"
- min_width="420"
- name="Test Floater"
- title="LAYOUTSTACK TESTS"
- width="420">
- <layout_stack name="test_stack"
- left="0"
- top="0"
- width="100"
- height="250"
- follows="left|top|bottom"
- orientation="vertical">
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- visible="false"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- visible="true"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- </layout_stack>
- <layout_stack name="test_stack"
- left_pad="5"
- top="0"
- width="100"
- height="250"
- follows="left|top|bottom"
- orientation="vertical">
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="100"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- visible="false"
- bg_alpha_color="blue"
- height="100"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="fixed"
- auto_resize="false"
- user_resize="true"
- height="50"
- min_height="10"
- bg_alpha_color="green"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="fixed"
+ can_resize="true"
+ can_close="true"
+ bevel_style="in"
+ height="300"
+ layout="topleft"
+ min_height="40"
+ min_width="420"
+ name="Test Floater"
+ title="LAYOUTSTACK TESTS"
+ width="420">
+ <layout_stack name="test_stack"
+ left="0"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ visible="false"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ visible="true"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ visible="false"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="fixed"
+ auto_resize="false"
+ user_resize="true"
+ height="50"
+ min_height="10"
+ bg_alpha_color="green"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
auto_resize="false"
- user_resize="true"
+ user_resize="true"
height="50"
min_height="10"
bg_alpha_color="green"
background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="100"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="100"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="100"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="100"
- visible="true"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- </layout_stack>
- <layout_stack name="test_stack"
- left_pad="5"
- top="0"
- width="100"
- height="250"
- follows="left|top|bottom"
- orientation="vertical">
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- height="11"
- bg_alpha_color="blue"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="fixed"
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="100"
+ visible="true"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ height="11"
+ bg_alpha_color="blue"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="fixed"
auto_resize="false"
- user_resize="true"
+ user_resize="true"
height="50"
bg_alpha_color="green"
background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- </layout_stack>
- <layout_stack name="test_stack"
- left_pad="5"
- top="0"
- width="100"
- height="250"
- follows="left|top|bottom"
- orientation="vertical">
- <layout_panel name="fixed"
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="test_stack"
+ left_pad="5"
+ top="0"
+ width="100"
+ height="250"
+ follows="left|top|bottom"
+ orientation="vertical">
+ <layout_panel name="fixed"
auto_resize="false"
- user_resize="true"
+ user_resize="true"
height="50"
bg_alpha_color="green"
background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="fixed"
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
auto_resize="false"
- user_resize="true"
+ user_resize="true"
height="50"
bg_alpha_color="green"
background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="fixed"
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="fixed"
auto_resize="false"
- user_resize="true"
+ user_resize="true"
height="50"
bg_alpha_color="green"
background_visible="true">
- <text follows="top|left|right" halign="center" text_color="black">fixed</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- <layout_panel name="flex"
- auto_resize="true"
- user_resize="true"
- bg_alpha_color="blue"
- height="11"
- min_height="0"
- background_visible="true">
- <text follows="top|left|right" halign="center" text_color="white">flex</text>
- </layout_panel>
- </layout_stack>
+ <text follows="top|left|right" halign="center" text_color="black">fixed</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ <layout_panel name="flex"
+ auto_resize="true"
+ user_resize="true"
+ bg_alpha_color="blue"
+ height="11"
+ min_height="0"
+ background_visible="true">
+ <text follows="top|left|right" halign="center" text_color="white">flex</text>
+ </layout_panel>
+ </layout_stack>
</floater>
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 d122d7491c..3a66911389 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -48,42 +48,28 @@
</text>
<!-- mode selector -->
- <radio_group
+ <combo_box
control_name="mode_selection"
height="20"
layout="topleft"
- left="0"
- top_pad="80"
+ left="6"
+ top_pad="77"
name="mode_selection"
- follows="left|top">
- <radio_item
+ follows="left|top"
+ width="120">
+ <combo_box.item
label="Inventory"
name="inventory"
- top_delta="20"
- layout="topleft"
- height="16"
- left="0"
- value="0"
- width="70" />
- <radio_item
+ value="0" />
+ <combo_box.item
label="Local"
- left_pad="0"
- layout="topleft"
- top_delta="0"
- height="16"
name="local"
- value="1"
- width="50" />
- <radio_item
+ value="1" />
+ <combo_box.item
label="Bake"
- left_pad="0"
- layout="topleft"
- top_delta="0"
- height="16"
name="bake"
- value="2"
- width="50" />
- </radio_group>
+ value="2" />
+ </combo_box>
<!-- -->
<text
@@ -92,12 +78,11 @@
follows="left|top"
height="14"
layout="topleft"
- left_delta="12"
- name="unknown"
+ left="8"
+ name="size_lbl"
top_pad="4">
- Size: [DIMENSIONS]
+ [DIMENSIONS]
</text>
-
<!-- middle: inventory mode -->
<button
@@ -138,20 +123,21 @@
image_selected="eye_button_active.tga"
image_unselected="eye_button_inactive.tga"
layout="topleft"
- left_delta="-80"
- top_delta="-25"
+ left="18"
+ top_delta="-23"
name="Pipette"
width="28" />
<text
follows="left|bottom"
- height="20"
+ height="40"
layout="topleft"
left="8"
name="preview_disabled"
- top="266"
+ top="285"
value="Preview Disabled"
+ word_wrap="true"
visible="false"
- width="120" />
+ width="87" />
<filter_editor
follows="left|top|right"
height="23"
@@ -161,7 +147,7 @@
name="inventory search editor"
top="20"
width="231" />
- <inventory_panel
+ <asset_filtered_inv_panel
allow_multi_select="false"
bg_visible="true"
bg_alpha_color="DkGray2"
@@ -172,7 +158,8 @@
left_delta="0"
name="inventory panel"
top_pad="4"
- width="231" />
+ width="231"
+ filter_asset_type="texture"/>
<check_box
height="14"
initial_value="false"
@@ -301,7 +288,8 @@
height="20"
initial_value="false"
label="Hide Base Mesh Region"
- layout="topleft"
+
+layout="topleft"
name="hide_base_mesh_region"
left_delta="0"
top_pad="10"
@@ -315,7 +303,7 @@
label="OK"
label_selected="OK"
layout="topleft"
- left="95"
+ left="176"
top="-30"
name="Select"
width="100" />
@@ -338,5 +326,5 @@
left="6"
name="apply_immediate_check"
top_delta="0"
- width="120" />
+ width="150" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 2d5263b78f..d88c267a95 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -12,6 +12,7 @@
<file>msyh.ttc</file>
<file load_collection="true">Cambria.ttc</file>
<file>malgun.ttf</file>
+ <file>micross.ttf</file>
</os>
<os name="Mac">
<file>ヒラギノ角ゴシック W3.ttc</file>
@@ -21,9 +22,11 @@
<file>AppleGothic.dfont</file>
<file>AppleGothic.ttf</file>
<file>AppleSDGothicNeo-Regular.otf</file>
+ <file>AppleSDGothicNeo.ttc</file>
<file>åŽæ–‡ç»†é»‘.ttf</file>
<file>PingFang.ttc</file>
<file>STIXGeneral.otf</file>
+ <file>Thonburi.ttc</file>
</os>
</font>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 38f4b7715f..7ad692038e 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -173,16 +173,13 @@
parameter="avatar_render_settings" />
</menu_item_call>
</context_menu>
- <menu_item_separator
- layout="topleft" name="Impostor seperator"/>
-
<menu_item_call
enabled="false"
label="Block Particle Owner"
name="Mute Particle">
<menu_item_call.on_click
function="Particle.Mute" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
</context_menu>
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 59faf6a9f5..26b1c86c53 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -4,28 +4,7 @@
name="Attachment Pie">
<menu_item_call
enabled="false"
- label="Touch"
- layout="topleft"
- name="Attachment Object Touch">
- <menu_item_call.on_click
- function="Object.Touch" />
- <menu_item_call.on_enable
- function="Object.EnableTouch"
- name="EnableTouch"/>
- </menu_item_call>
- <!--menu_item_call
- label="Stand Up"
- layout="topleft"
- name="Stand Up">
- <menu_item_call.on_click
- function="Self.StandUp"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableStandUp" />
- </menu_item_call-->
- <menu_item_call
- enabled="false"
- label="Edit"
+ label="Edit item"
layout="topleft"
name="Edit...">
<menu_item_call.on_click
@@ -35,7 +14,7 @@
</menu_item_call>
<menu_item_call
enabled="false"
- label="Detach"
+ label="Detach item"
layout="topleft"
name="Detach">
<menu_item_call.on_click
@@ -43,98 +22,278 @@
<menu_item_call.on_enable
function="Attachment.EnableDetach" />
</menu_item_call>
- <menu_item_separator
- layout="topleft" />
-
<menu_item_call
- label="Sit Down"
+ enabled="false"
+ label="Touch item"
layout="topleft"
- name="Sit Down Here">
+ name="Attachment Object Touch">
<menu_item_call.on_click
- function="Self.SitDown"
- parameter="" />
+ function="Object.Touch" />
<menu_item_call.on_enable
- function="Self.EnableSitDown" />
+ function="Object.EnableTouch"
+ name="EnableTouch"/>
</menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
<menu_item_call
-label="Stand Up"
-layout="topleft"
-name="Stand Up">
+ label="Now wearing..."
+ name="NowWearing">
<menu_item_call.on_click
- function="Self.StandUp"
- parameter="" />
+ function="NowWearing" />
<menu_item_call.on_enable
- function="Self.EnableStandUp" />
+ function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
<menu_item_call
- label="My Appearance"
+ label="My Outfits..."
name="Change Outfit">
<menu_item_call.on_click
function="CustomizeAvatar" />
<menu_item_call.on_enable
function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
- <menu_item_call label="Edit My Outfit"
-layout="topleft"
-name="Edit Outfit">
+ <menu_item_call label="Hover height..."
+ layout="topleft"
+ name="Hover Height">
<menu_item_call.on_click
- function="EditOutfit" />
+ function="HoverHeight" />
<menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
+ function="Edit.EnableHoverHeight" />
</menu_item_call>
- <menu_item_call label="Edit My Shape"
+ <menu_item_call label="Shape..."
layout="topleft"
- name="Edit My Shape">
+ name="Edit Shape">
<menu_item_call.on_click
function="EditShape" />
<menu_item_call.on_enable
function="Edit.EnableEditShape" />
</menu_item_call>
- <menu_item_call label="Hover Height"
- layout="topleft"
- name="Hover Height">
- <menu_item_call.on_click
- function="HoverHeight" />
- <menu_item_call.on_enable
- function="Edit.EnableHoverHeight" />
+ <menu_item_call label="Edit outfit parts..."
+ layout="topleft"
+ name="Edit Outfit">
+ <menu_item_call.on_click
+ function="EditOutfit" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
- <menu_item_call label="Reset Skeleton"
+ <context_menu
+ label="Take off"
+ layout="topleft"
+ name="Take Off &gt;">
+ <context_menu
+ label="Clothes"
+ layout="topleft"
+ name="Clothes &gt;">
+ <menu_item_call
+ enabled="false"
+ label="Shirt"
layout="topleft"
- name="Reset Skeleton">
- <menu_item_call.on_click
- function="Avatar.ResetSkeleton" />
- </menu_item_call>
- <menu_item_call label="Reset Skeleton And Animations"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Pants"
layout="topleft"
- name="Reset Skeleton And Animations">
- <menu_item_call.on_click
- function="Avatar.ResetSkeletonAndAnimations" />
- </menu_item_call>
-
+ name="Pants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="pants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shoes" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Socks"
+ layout="topleft"
+ name="Socks">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="socks" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="jacket" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="gloves" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Undershirt"
+ layout="topleft"
+ name="Self Undershirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="undershirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Underpants"
+ layout="topleft"
+ name="Self Underpants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="underpants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Tattoo"
+ layout="topleft"
+ name="Self Tattoo">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="tattoo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Physics"
+ layout="topleft"
+ name="Self Physics">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="physics" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="physics" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Alpha"
+ layout="topleft"
+ name="Self Alpha">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="alpha" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="All Clothes"
+ layout="topleft"
+ name="All Clothes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="all" />
+ </menu_item_call>
+ </context_menu>
+ <context_menu
+ label="HUD"
+ layout="topleft"
+ name="Detach Self HUD" />
+ <context_menu
+ label="Detach"
+ layout="topleft"
+ name="Detach Self" />
+ <menu_item_call
+ label="Detach All"
+ layout="topleft"
+ name="Detach All">
+ <menu_item_call.on_click
+ function="Self.RemoveAllAttachments"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="Self.EnableRemoveAllAttachments" />
+ </menu_item_call>
+ </context_menu>
+ <menu_item_separator/>
<menu_item_call
- label="My Friends"
+ label="Sit / stand"
layout="topleft"
- name="Friends...">
+ name="Sit stand">
<menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="friends_panel" />
+ function="Self.ToggleSitStand"/>
+ <menu_item_call.on_enable
+ function="Self.EnableSitStand" />
</menu_item_call>
<menu_item_call
- label="My Groups"
- layout="topleft"
- name="Groups...">
+ label="Fly / land"
+ name="Fly land">
<menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="groups_panel" />
+ function="Agent.toggleFlying" />
+ <menu_item_call.on_enable
+ function="Agent.enableFlyLand" />
</menu_item_call>
<menu_item_call
- label="My Profile"
- layout="topleft"
- name="Profile...">
+ label="Stop animations"
+ name="Stop Animating My Avatar">
<menu_item_call.on_click
- function="ShowAgentProfile"
- parameter="agent" />
+ function="Tools.StopAllAnimations" />
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="Reset skeleton"
+ layout="topleft"
+ name="Reset Skeleton">
+ <menu_item_call.on_click
+ function="Avatar.ResetSkeleton" />
+ </menu_item_call>
+ <menu_item_call label="Reset skeleton and animations"
+ layout="topleft"
+ name="Reset Skeleton And Animations">
+ <menu_item_call.on_click
+ function="Avatar.ResetSkeletonAndAnimations" />
</menu_item_call>
<menu_item_call
label="Debug Textures"
@@ -152,27 +311,27 @@ name="Edit Outfit">
<menu_item_call.on_visible
function="Advanced.EnableAppearanceToXML"/>
</menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- enabled="false"
- label="Drop"
- layout="topleft"
- name="Drop">
- <menu_item_call.on_click
- function="Attachment.Drop" />
- <menu_item_call.on_enable
- function="Attachment.EnableDrop" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
<menu_item_call
enabled="false"
label="Block Particle Owner"
name="Mute Particle">
<menu_item_call.on_click
function="Particle.Mute" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
+
+ <menu_item_separator
+ layout="topleft" />
+
+ <menu_item_call
+ enabled="false"
+ label="Drop item"
+ layout="topleft"
+ name="Drop">
+ <menu_item_call.on_click
+ function="Attachment.Drop" />
+ <menu_item_call.on_enable
+ function="Attachment.EnableDrop" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index f9fb847910..acbb9b860d 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -165,16 +165,13 @@
</menu_item_call>
</context_menu>
- <menu_item_separator
- layout="topleft" name="Impostor seperator"/>
-
<menu_item_call
enabled="false"
label="Block Particle Owner"
name="Mute Particle">
<menu_item_call.on_click
function="Particle.Mute" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
</context_menu>
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 9e181d0b6d..500b6fffc2 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -3,209 +3,16 @@
layout="topleft"
name="Self Pie">
<menu_item_call
- label="Sit Down"
+ label="Now wearing..."
layout="topleft"
- name="Sit Down Here">
+ name="NowWearing">
<menu_item_call.on_click
- function="Self.SitDown"
- parameter="" />
+ function="NowWearing" />
<menu_item_call.on_enable
- function="Self.EnableSitDown" />
+ function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
<menu_item_call
- label="Stand Up"
- layout="topleft"
- name="Stand Up">
- <menu_item_call.on_click
- function="Self.StandUp"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableStandUp" />
- </menu_item_call>
- <context_menu
- label="Take Off"
- layout="topleft"
- name="Take Off &gt;">
- <context_menu
- label="Clothes"
- layout="topleft"
- name="Clothes &gt;">
- <menu_item_call
- enabled="false"
- label="Shirt"
- layout="topleft"
- name="Shirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Pants"
- layout="topleft"
- name="Pants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="pants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Skirt"
- layout="topleft"
- name="Skirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="skirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Shoes"
- layout="topleft"
- name="Shoes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shoes" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Socks"
- layout="topleft"
- name="Socks">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="socks" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Jacket"
- layout="topleft"
- name="Jacket">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="jacket" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Gloves"
- layout="topleft"
- name="Gloves">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="gloves" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Undershirt"
- layout="topleft"
- name="Self Undershirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="undershirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Underpants"
- layout="topleft"
- name="Self Underpants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="underpants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Tattoo"
- layout="topleft"
- name="Self Tattoo">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="tattoo" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Physics"
- layout="topleft"
- name="Self Physics">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="physics" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="physics" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Alpha"
- layout="topleft"
- name="Self Alpha">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="alpha" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="All Clothes"
- layout="topleft"
- name="All Clothes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="all" />
- </menu_item_call>
- </context_menu>
- <context_menu
- label="HUD"
- layout="topleft"
- name="Object Detach HUD" />
- <context_menu
- label="Detach"
- layout="topleft"
- name="Object Detach" />
- <menu_item_call
- label="Detach All"
- layout="topleft"
- name="Detach All">
- <menu_item_call.on_click
- function="Self.RemoveAllAttachments"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableRemoveAllAttachments" />
- </menu_item_call>
- </context_menu>
- <menu_item_call
- label="My Appearance"
+ label="My Outfits..."
layout="topleft"
name="Chenge Outfit">
<menu_item_call.on_click
@@ -213,66 +20,250 @@
<menu_item_call.on_enable
function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
- <menu_item_call label="Edit My Outfit"
- layout="topleft"
- name="Edit Outfit">
- <menu_item_call.on_click
- function="EditOutfit" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
+ <menu_item_call label="Hover height..."
+ layout="topleft"
+ name="Hover Height">
+ <menu_item_call.on_click
+ function="HoverHeight" />
+ <menu_item_call.on_enable
+ function="Edit.EnableHoverHeight" />
</menu_item_call>
- <menu_item_call label="Edit My Shape"
+ <menu_item_call label="Shape..."
layout="topleft"
- name="Edit My Shape">
+ name="Edit Shape">
<menu_item_call.on_click
function="EditShape" />
<menu_item_call.on_enable
function="Edit.EnableEditShape" />
</menu_item_call>
- <menu_item_call label="Hover Height"
- layout="topleft"
- name="Hover Height">
- <menu_item_call.on_click
- function="HoverHeight" />
- <menu_item_call.on_enable
- function="Edit.EnableHoverHeight" />
+ <menu_item_call
+ label="Edit outfit parts..."
+ layout="topleft"
+ name="Edit Outfit">
+ <menu_item_call.on_click
+ function="EditOutfit" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
- <menu_item_call label="Reset Skeleton"
+ <context_menu
+ label="Take off"
+ layout="topleft"
+ name="Take Off &gt;">
+ <context_menu
+ label="Clothes"
+ layout="topleft"
+ name="Clothes &gt;">
+ <menu_item_call
+ enabled="false"
+ label="Shirt"
+ layout="topleft"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Pants"
+ layout="topleft"
+ name="Pants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="pants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shoes" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Socks"
+ layout="topleft"
+ name="Socks">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="socks" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="jacket" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="gloves" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Undershirt"
+ layout="topleft"
+ name="Self Undershirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="undershirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Underpants"
+ layout="topleft"
+ name="Self Underpants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="underpants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Tattoo"
+ layout="topleft"
+ name="Self Tattoo">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="tattoo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Physics"
+ layout="topleft"
+ name="Self Physics">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="physics" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="physics" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Alpha"
+ layout="topleft"
+ name="Self Alpha">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="alpha" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="All Clothes"
+ layout="topleft"
+ name="All Clothes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="all" />
+ </menu_item_call>
+ </context_menu>
+ <context_menu
+ label="HUD"
+ layout="topleft"
+ name="Object Detach HUD" />
+ <context_menu
+ label="Detach"
+ layout="topleft"
+ name="Object Detach" />
+ <menu_item_call
+ label="Detach All"
+ layout="topleft"
+ name="Detach All">
+ <menu_item_call.on_click
+ function="Self.RemoveAllAttachments"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="Self.EnableRemoveAllAttachments" />
+ </menu_item_call>
+ </context_menu>
+ <menu_item_separator/>
+ <menu_item_call
+ label="Sit / stand"
+ layout="topleft"
+ name="Sit stand">
+ <menu_item_call.on_click
+ function="Self.ToggleSitStand"/>
+ <menu_item_call.on_enable
+ function="Self.EnableSitStand" />
+ </menu_item_call>
+ <menu_item_call
+ label="Fly / land"
+ name="Fly land">
+ <menu_item_call.on_click
+ function="Agent.toggleFlying" />
+ <menu_item_call.on_enable
+ function="Agent.enableFlyLand" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop animations"
+ name="Stop Animating My Avatar">
+ <menu_item_call.on_click
+ function="Tools.StopAllAnimations" />
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="Reset skeleton"
layout="topleft"
name="Reset Skeleton">
<menu_item_call.on_click
function="Avatar.ResetSkeleton" />
- </menu_item_call>
- <menu_item_call label="Reset Skeleton And Animations"
+ </menu_item_call>
+ <menu_item_call label="Reset skeleton and animations"
layout="topleft"
name="Reset Skeleton And Animations">
<menu_item_call.on_click
function="Avatar.ResetSkeletonAndAnimations" />
</menu_item_call>
- <menu_item_call
- label="My Friends"
- layout="topleft"
- name="Friends...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="friends_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Groups"
- layout="topleft"
- name="Groups...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="groups_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Profile"
- layout="topleft"
- name="Profile...">
- <menu_item_call.on_click
- function="ShowAgentProfile"
- parameter="agent" />
- </menu_item_call>
<menu_item_call
label="Debug Textures"
name="Debug...">
@@ -289,8 +280,6 @@
<menu_item_call.on_visible
function="Advanced.EnableAppearanceToXML"/>
</menu_item_call>
- <menu_item_separator
- layout="topleft" />
<menu_item_call
enabled="false"
label="Block Particle Owner"
@@ -298,7 +287,7 @@
<menu_item_call.on_click
function="Particle.Mute" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
index c402100fb1..3f545c936d 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
@@ -3,6 +3,26 @@
layout="topleft"
name="COF Attachment">
<menu_item_call
+ label="Touch"
+ layout="topleft"
+ name="touch_attach">
+ <on_click
+ function="Attachment.Touch" />
+ <on_enable
+ function="Attachment.OnEnable"
+ parameter="touch" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit_item">
+ <on_click
+ function="Attachment.Edit" />
+ <on_enable
+ function="Attachment.OnEnable"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_call
label="Detach"
layout="topleft"
name="detach">
diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml
index be380e11e5..0eab7c451b 100644
--- a/indra/newview/skins/default/xui/en/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/en/menu_favorites.xml
@@ -21,12 +21,12 @@
parameter="about" />
</menu_item_call>
<menu_item_call
- label="Copy SLurl"
+ label="Move to Landmarks"
layout="topleft"
- name="Copy slurl">
+ name="Move to Landmarks">
<menu_item_call.on_click
function="Favorites.DoToSelected"
- parameter="copy_slurl" />
+ parameter="move_to_landmarks" />
</menu_item_call>
<menu_item_call
label="Show on Map"
@@ -36,6 +36,25 @@
function="Favorites.DoToSelected"
parameter="show_on_map" />
</menu_item_call>
+ <menu_item_call
+ label="Copy SLurl"
+ layout="topleft"
+ name="Copy slurl">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="copy_slurl" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create Pick"
+ layout="topleft"
+ name="create_pick">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="create_pick" />
+ <menu_item_call.on_enable
+ function="Favorites.EnableSelected"
+ parameter="create_pick" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
@@ -59,10 +78,14 @@
function="Favorites.EnableSelected"
parameter="can_paste" />
</menu_item_call>
-
- <menu_item_separator
- layout="topleft" />
-
+ <menu_item_call
+ label="Rename"
+ layout="topleft"
+ name="rename">
+ <menu_item_call.on_click
+ function="Favorites.DoToSelected"
+ parameter="rename" />
+ </menu_item_call>
<menu_item_call
label="Delete"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
index 1b08767edc..99ca910062 100755
--- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
@@ -42,7 +42,7 @@
parameter="take_off" />
</menu_item_call>
<menu_item_call
- label="Upload Photo (L$10)"
+ label="Upload Photo (L$[UPLOAD_COST])"
layout="topleft"
name="upload_photo">
<on_click
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 3bdbbb04d7..eda9739976 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -322,6 +322,41 @@
</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">
@@ -775,14 +810,6 @@
<menu_item_separator
layout="topleft"
name="Wearable And Object Separator"/>
- <menu_item_call
- label="Detach From Yourself"
- layout="topleft"
- name="Detach From Yourself">
- <menu_item_call.on_click
- function="Inventory.DoToSelected"
- parameter="detach" />
- </menu_item_call>
<!-- COMMENTED OUT for DEV-32347 -->
<!--
<menu_item_call
@@ -811,6 +838,14 @@
layout="topleft"
name="Attach To HUD" />
<menu_item_call
+ label="Touch"
+ layout="topleft"
+ name="Attachment Touch">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="touch" />
+ </menu_item_call>
+ <menu_item_call
label="Edit"
layout="topleft"
name="Wearable Edit">
@@ -827,6 +862,14 @@
parameter="wear_add" />
</menu_item_call>
<menu_item_call
+ label="Detach From Yourself"
+ layout="topleft"
+ name="Detach From Yourself">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="detach" />
+ </menu_item_call>
+ <menu_item_call
label="Take Off"
layout="topleft"
name="Take Off">
@@ -834,6 +877,25 @@
function="Inventory.DoToSelected"
parameter="take_off" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Settings Separator" />
+ <menu_item_call
+ name="Settings Apply Local"
+ layout="topleft"
+ label="Apply Only To Myself">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="apply_settings_local" />
+ </menu_item_call>
+ <menu_item_call
+ name="Settings Apply Parcel"
+ layout="topleft"
+ label="Apply To Parcel">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="apply_settings_parcel" />
+ </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 29724b0270..3385a29a6c 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -56,7 +56,7 @@
function="File.VisibleUploadModel"/>
</menu_item_call>
<menu_item_call
- label="Bulk (L$[COST] per file)..."
+ label="Bulk..."
layout="topleft"
name="Bulk Upload">
<menu_item_call.on_click
@@ -253,4 +253,41 @@
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> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml
new file mode 100644
index 0000000000..46193f4a7a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_search_visibility"
+ visible="false">
+ <menu_item_check
+ label="Search Trash"
+ layout="topleft"
+ name="search_trash">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="toggle_search_trash" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="toggle_search_trash" />
+ </menu_item_check>
+ <menu_item_check
+ label="Search Library"
+ layout="topleft"
+ name="search_library">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="toggle_search_library" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="toggle_search_library" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Include links"
+ layout="topleft"
+ name="include_links">
+ <on_click
+ function="Inventory.GearDefault.Custom.Action"
+ parameter="include_links" />
+ <on_check
+ function="Inventory.GearDefault.Check"
+ parameter="include_links" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 07b3cc3bd8..96fac1c6e8 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -57,20 +57,13 @@
tear_off="true"
name="Help">
<menu_item_call
- label="How to..."
+ label="Guidebook"
name="How To"
shortcut="F1">
<menu_item_call.on_click
function="Help.ToggleHowTo"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Quickstart"
- name="Quickstart">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/>
- </menu_item_call>
<menu_item_separator/>
<menu_item_call
label="Knowledge Base"
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index 61cb74f230..32d9d28434 100644
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -40,7 +40,7 @@
parameter="take_off" />
</menu_item_call>
<menu_item_call
- label="Upload Photo (L$10)"
+ label="Upload Photo (L$[UPLOAD_COST])"
layout="topleft"
name="upload_photo">
<on_click
diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml
index ebb49c9004..a408e6136c 100644
--- a/indra/newview/skins/default/xui/en/menu_picks.xml
+++ b/indra/newview/skins/default/xui/en/menu_picks.xml
@@ -3,7 +3,17 @@
layout="topleft"
name="Picks">
<menu_item_call
- label="Info"
+ label="Teleport"
+ layout="topleft"
+ name="pick_teleport">
+ <menu_item_call.on_click
+ function="Pick.Teleport" />
+ <menu_item_call.on_enable
+ function="Pick.Enable"
+ parameter="teleport" />
+ </menu_item_call>
+ <menu_item_call
+ label="View Pick"
layout="topleft"
name="pick_info">
<menu_item_call.on_click
@@ -13,7 +23,7 @@
parameter="info" />
</menu_item_call>
<menu_item_call
- label="Edit"
+ label="Edit Pick"
layout="topleft"
name="pick_edit"
visible="false">
@@ -24,17 +34,7 @@
parameter="edit" />
</menu_item_call>
<menu_item_call
- label="Teleport"
- layout="topleft"
- name="pick_teleport">
- <menu_item_call.on_click
- function="Pick.Teleport" />
- <menu_item_call.on_enable
- function="Pick.Enable"
- parameter="teleport" />
- </menu_item_call>
- <menu_item_call
- label="Map"
+ label="Show on map"
layout="topleft"
name="pick_map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
index e3a39a1242..ad49f7c3a8 100644
--- a/indra/newview/skins/default/xui/en/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
@@ -1,27 +1,30 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu
+<toggleable_menu
layout="topleft"
left="0"
mouse_opaque="false"
- name="menu_folder_gear"
+ name="menu_create"
visible="false">
<menu_item_call
- label="Add Folder"
+ label="Landmark current location"
layout="topleft"
- name="add_folder">
+ name="add_landmark">
<on_click
function="Places.LandmarksGear.Add.Action"
- parameter="category" />
+ parameter="add_landmark_root" />
<on_enable
function="Places.LandmarksGear.Enable"
- parameter="category" />
+ parameter="add_landmark_root" />
</menu_item_call>
<menu_item_call
- label="Add Landmark"
+ label="Create folder"
layout="topleft"
- name="add_landmark">
+ name="add_folder">
<on_click
function="Places.LandmarksGear.Add.Action"
- parameter="add_landmark" />
+ parameter="category_root" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="category_root" />
</menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
index 1aeb166e01..e9ada52a8f 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
@@ -7,15 +7,18 @@
name="menu_folder_gear"
visible="false">
<menu_item_call
- label="Add Landmark"
+ label="Landmark current location"
layout="topleft"
name="add_landmark">
<on_click
function="Places.LandmarksGear.Add.Action"
parameter="add_landmark" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="add_landmark" />
</menu_item_call>
<menu_item_call
- label="Add Folder"
+ label="Create subfolder"
layout="topleft"
name="add_folder">
<on_click
@@ -24,6 +27,9 @@
<on_enable
function="Places.LandmarksGear.Enable"
parameter="category" />
+ <on_visible
+ function="Places.LandmarksGear.Enable"
+ parameter="category" />
</menu_item_call>
<menu_item_call
label="Restore Item"
@@ -120,37 +126,4 @@
function="Places.LandmarksGear.Enable"
parameter="collapse" />
</menu_item_call>
- <menu_item_call
- label="Expand all folders"
- layout="topleft"
- name="expand_all">
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="expand_all" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="expand_all" />
- </menu_item_call>
- <menu_item_call
- label="Collapse all folders"
- layout="topleft"
- name="collapse_all">
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="collapse_all" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="collapse_all" />
- </menu_item_call>
- <menu_item_check
- label="Sort by Date"
- layout="topleft"
- name="sort_by_date">
- <on_check
- function="Places.LandmarksGear.Check"
- parameter="sort_by_date" />
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="sort_by_date" />
- </menu_item_check>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
index ff5fdd3795..c89b498ddf 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
@@ -18,7 +18,18 @@
parameter="teleport" />
</menu_item_call>
<menu_item_call
- label="More Information"
+ label="Share"
+ layout="topleft"
+ name="share">
+ <on_click
+ function="Places.LandmarksGear.Custom.Action"
+ parameter="share" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="share" />
+ </menu_item_call>
+ <menu_item_call
+ label="View/Edit Landmark"
layout="topleft"
name="more_info">
<on_click
@@ -29,6 +40,28 @@
parameter="more_info" />
</menu_item_call>
<menu_item_call
+ label="Move to Landmarks"
+ layout="topleft"
+ name="Move to Landmarks">
+ <menu_item_call.on_click
+ function="Places.LandmarksGear.Custom.Action"
+ parameter="move_to_landmarks" />
+ <menu_item_call.on_visible
+ function="Places.LandmarksGear.Enable"
+ parameter="move_to_landmarks" />
+ </menu_item_call>
+ <menu_item_call
+ label="Move to Favorites"
+ layout="topleft"
+ name="Move to Favorites">
+ <menu_item_call.on_click
+ function="Places.LandmarksGear.Custom.Action"
+ parameter="move_to_favorites" />
+ <menu_item_call.on_visible
+ function="Places.LandmarksGear.Enable"
+ parameter="move_to_favorites" />
+ </menu_item_call>
+ <menu_item_call
label="Show on Map"
layout="topleft"
name="show_on_map">
@@ -39,26 +72,27 @@
function="Places.LandmarksGear.Enable"
parameter="show_on_map" />
</menu_item_call>
- <menu_item_separator
- layout="topleft" />
<menu_item_call
- label="Add Landmark"
+ label="Copy SLurl"
layout="topleft"
- name="add_landmark">
+ name="copy_slurl">
<on_click
- function="Places.LandmarksGear.Add.Action"
- parameter="add_landmark" />
- </menu_item_call>
+ function="Places.LandmarksGear.CopyPaste.Action"
+ parameter="copy_slurl" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="copy_slurl" />
+ </menu_item_call>
<menu_item_call
- label="Add Folder"
+ label="Create Pick"
layout="topleft"
- name="add_folder">
+ name="create_pick">
<on_click
- function="Places.LandmarksGear.Add.Action"
- parameter="category" />
+ function="Places.LandmarksGear.Custom.Action"
+ parameter="create_pick" />
<on_enable
function="Places.LandmarksGear.Enable"
- parameter="category" />
+ parameter="create_pick" />
</menu_item_call>
<menu_item_call
label="Restore Item"
@@ -82,7 +116,7 @@
parameter="cut" />
</menu_item_call>
<menu_item_call
- label="Copy Landmark"
+ label="Copy"
layout="topleft"
name="copy_landmark">
<on_click
@@ -90,17 +124,6 @@
parameter="copy" />
</menu_item_call>
<menu_item_call
- label="Copy SLurl"
- layout="topleft"
- name="copy_slurl">
- <on_click
- function="Places.LandmarksGear.CopyPaste.Action"
- parameter="copy_slurl" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="copy_slurl" />
- </menu_item_call>
- <menu_item_call
label="Paste"
layout="topleft"
name="paste">
@@ -133,53 +156,4 @@
function="Places.LandmarksGear.Enable"
parameter="delete" />
</menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Expand all folders"
- layout="topleft"
- name="expand_all">
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="expand_all" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="expand_all" />
- </menu_item_call>
- <menu_item_call
- label="Collapse all folders"
- layout="topleft"
- name="collapse_all">
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="collapse_all" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="collapse_all" />
- </menu_item_call>
- <menu_item_check
- label="Sort by Date"
- layout="topleft"
- name="sort_by_date">
- <on_check
- function="Places.LandmarksGear.Check"
- parameter="sort_by_date" />
- <on_click
- function="Places.LandmarksGear.Folding.Action"
- parameter="sort_by_date" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="sort_by_date" />
- </menu_item_check>
- <menu_item_call
- label="Create Pick"
- layout="topleft"
- name="create_pick">
- <on_click
- function="Places.LandmarksGear.Custom.Action"
- parameter="create_pick" />
- <on_enable
- function="Places.LandmarksGear.Enable"
- parameter="create_pick" />
- </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
new file mode 100644
index 0000000000..4193a72e2e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_sorter_gear"
+ visible="false">
+ <menu_item_call
+ label="Expand all folders"
+ layout="topleft"
+ name="expand_all">
+ <on_click
+ function="Places.LandmarksGear.Folding.Action"
+ parameter="expand_all" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="expand_all" />
+ </menu_item_call>
+ <menu_item_call
+ label="Collapse all folders"
+ layout="topleft"
+ name="collapse_all">
+ <on_click
+ function="Places.LandmarksGear.Folding.Action"
+ parameter="collapse_all" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="collapse_all" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Sort by Date"
+ layout="topleft"
+ name="sort_by_date">
+ <on_check
+ function="Places.LandmarksGear.Check"
+ parameter="sort_by_date" />
+ <on_click
+ function="Places.LandmarksGear.Folding.Action"
+ parameter="sort_by_date" />
+ <on_enable
+ function="Places.LandmarksGear.Enable"
+ parameter="sort_by_date" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_save_settings.xml b/indra/newview/skins/default/xui/en/menu_save_settings.xml
new file mode 100644
index 0000000000..84dacaa8b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_save_settings.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ height="602"
+ layout="topleft"
+ mouse_opaque="false"
+ name="save_settings_menu"
+ width="120">
+ <menu_item_check
+ name="save_settings"
+ label="Save">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="save" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="save"/>
+ </menu_item_check>
+ <menu_item_check
+ name="save_as_new_settings"
+ label="Save As">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="saveas" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="saveas" />
+ </menu_item_check>
+ <menu_item_check
+ name="commit_changes"
+ label="Commit">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="commit" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="commit" />
+ </menu_item_check>
+ <menu_item_check
+ name="apply_local"
+ label="Apply Only To Myself">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="local" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="local" />
+ </menu_item_check>
+ <menu_item_check
+ name="apply_parcel"
+ label="Apply To Parcel">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="parcel" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="parcel" />
+ </menu_item_check>
+ <menu_item_check
+ name="apply_region"
+ label="Apply To Region">
+ <menu_item_check.on_check
+ function="FlyoutCombo.Button.Check"
+ userdata="region" />
+ <menu_item_check.on_click
+ function="FlyoutCombo.Button.Action"
+ userdata="region" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
index db29d9cebc..49e52ebb8d 100644
--- a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
@@ -16,4 +16,12 @@
function="ScriptChiclet.Action"
parameter="end" />
</menu_item_call>
+ <menu_item_call
+ label="Close All Dialogs"
+ layout="topleft"
+ name="Close All">
+ <menu_item_call.on_click
+ function="ScriptChiclet.Action"
+ parameter="close all" />
+ </menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_settings_add.xml b/indra/newview/skins/default/xui/en/menu_settings_add.xml
new file mode 100644
index 0000000000..a4782cfdc3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_settings_add.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ mouse_opaque="false"
+ name="menu_settings_add"
+ visible="false">
+ <menu_item_call
+ label="New Sky"
+ layout="topleft"
+ name="New Sky">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoCreate"
+ parameter="sky"/>
+ <menu_item_call.on_enable
+ function="MyEnvironments.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Water"
+ layout="topleft"
+ name="New Water">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoCreate"
+ parameter="water"/>
+ <menu_item_call.on_enable
+ function="MyEnvironments.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Day Cycle"
+ layout="topleft"
+ name="New Day Cycle">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoCreate"
+ parameter="daycycle"/>
+ <menu_item_call.on_enable
+ function="MyEnvironments.EnvironmentEnabled" />
+ </menu_item_call>
+</toggleable_menu> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/menu_settings_gear.xml b/indra/newview/skins/default/xui/en/menu_settings_gear.xml
new file mode 100644
index 0000000000..ea8e328407
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_settings_gear.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ mouse_opaque="false"
+ name="menu_settings_gear"
+ visible="false">
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit_settings">
+ <on_click
+ function="MyEnvironments.DoEdit" />
+ <on_enable
+ function="MyEnvironments.EnableAction"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Separator" />
+ <menu_item_call
+ name="Settings Apply Local"
+ layout="topleft"
+ label="Apply Only To Myself">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoApply"
+ parameter="local" />
+ </menu_item_call>
+ <menu_item_call
+ name="Settings Apply Parcel"
+ layout="topleft"
+ label="Apply To Parcel">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoApply"
+ parameter="parcel" />
+ <menu_item_call.on_enable
+ function="MyEnvironments.CanApply"
+ parameter="parcel"/>
+ </menu_item_call>
+ <menu_item_call
+ name="Settings Apply Region"
+ layout="topleft"
+ label="Apply To Region">
+ <menu_item_call.on_click
+ function="MyEnvironments.DoApply"
+ parameter="region" />
+ <menu_item_call.on_enable
+ function="MyEnvironments.CanApply"
+ parameter="region"/>
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Separator" />
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="copy_settings">
+ <on_click
+ function="MyEnvironments.CopyPaste"
+ parameter="copy" />
+ <on_enable
+ function="MyEnvironments.EnableAction"
+ parameter="copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="paste_settings">
+ <on_click
+ function="MyEnvironments.CopyPaste"
+ parameter="paste" />
+ <on_enable
+ function="MyEnvironments.EnableAction"
+ parameter="paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy UUID"
+ layout="topleft"
+ name="copy_uuid">
+ <on_click
+ function="MyEnvironments.CopyPaste"
+ parameter="copy_uuid" />
+ <on_enable
+ function="MyEnvironments.EnableAction"
+ parameter="copy_uuid" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
index bc7d4fe33b..c11d668698 100644
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
@@ -12,7 +12,8 @@
label="Expand all folders"
name="Expand all folders">
<menu_item_call.on_click
- function="TeleportHistory.ExpandAllFolders" />
+ function="TeleportHistory.GearMenu.Action"
+ parameter="expand_all" />
<on_enable
function="TeleportHistory.GearMenu.Enable"
parameter="expand_all" />
@@ -21,16 +22,10 @@
label="Collapse all folders"
name="Collapse all folders">
<menu_item_call.on_click
- function="TeleportHistory.CollapseAllFolders" />
+ function="TeleportHistory.GearMenu.Action"
+ parameter="collapse_all" />
<on_enable
function="TeleportHistory.GearMenu.Enable"
parameter="collapse_all" />
</menu_item_call>
- <menu_item_separator layout="topleft" />
- <menu_item_call
- label="Clear Teleport History"
- name="Clear Teleport History">
- <menu_item_call.on_click
- function="TeleportHistory.ClearTeleportHistory" />
- </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
index f939c3996d..153e5a70a9 100644
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
@@ -1,26 +1,52 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
+<toggleable_menu
+ name="Teleport History Item Menu"
layout="topleft"
- name="Teleport History Item Context Menu">
+ left="0"
+ mouse_opaque="false"
+ visible="false">
<menu_item_call
label="Teleport"
layout="topleft"
name="Teleport">
- <menu_item_call.on_click
- function="TeleportHistory.Teleport" />
+ <on_click
+ function="TeleportHistory.GearMenu.Action"
+ parameter="teleport" />
+ <on_enable
+ function="TeleportHistory.GearMenu.Enable"
+ parameter="teleport" />
</menu_item_call>
<menu_item_call
- label="More Information"
+ label="View"
layout="topleft"
name="More Information">
- <menu_item_call.on_click
- function="TeleportHistory.MoreInformation" />
+ <on_click
+ function="TeleportHistory.GearMenu.Action"
+ parameter="view" />
+ <on_enable
+ function="TeleportHistory.GearMenu.Enable"
+ parameter="view" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show on map"
+ layout="topleft"
+ name="show_on_map">
+ <on_click
+ function="TeleportHistory.GearMenu.Action"
+ parameter="show_on_map" />
+ <on_enable
+ function="TeleportHistory.GearMenu.Enable"
+ parameter="show_on_map" />
</menu_item_call>
<menu_item_call
label="Copy SLurl"
layout="topleft"
name="CopyToClipboard">
- <menu_item_call.on_click
- function="TeleportHistory.CopyToClipboard" />
+ <on_click
+ function="TeleportHistory.GearMenu.Action"
+ parameter="copy_slurl" />
+ <on_enable
+ function="TeleportHistory.GearMenu.Enable"
+ parameter="copy_slurl" />
</menu_item_call>
-</context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 3bab3aea55..c550f69d26 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -15,24 +15,6 @@
function="ShowAgentProfile"
parameter="agent" />
</menu_item_call>
- <menu_item_call
- label="Appearance..."
- name="ChangeOutfit"
- shortcut="control|O">
- <menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="appearance" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_call
- label="Choose an avatar..."
- name="Avatar Picker">
- <menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="avatar" />
- </menu_item_call>
- <menu_item_separator/>
<menu_item_check
label="Inventory..."
name="Inventory"
@@ -56,10 +38,10 @@
</menu_item_call>
<menu_item_call
label="Places..."
- name="Places">
+ name="Places"
+ shortcut="control|L">
<menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="places" />
+ function="Tools.Link"/>
</menu_item_call>
<menu_item_call
label="Picks..."
@@ -76,116 +58,31 @@
parameter="experiences"/>
</menu_item_call>
<menu_item_call
- label="My Scripts..."
- name="MyScripts">
- <menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="my_scripts"/>
- </menu_item_call>
- <menu_item_separator/>
- <menu_item_call
label="Camera Controls..."
- name="Camera Controls">
+ name="Camera Controls"
+ shortcut="control|K">
<menu_item_call.on_click
function="Floater.ToggleOrBringToFront"
parameter="camera" />
</menu_item_call>
- <menu
- create_jump_keys="true"
- label="Movement"
- name="Movement"
- tear_off="true">
- <menu_item_call
- label="Sit Down"
- layout="topleft"
- shortcut="alt|shift|S"
- name="Sit Down Here">
- <menu_item_call.on_click
- function="Self.SitDown"/>
- <menu_item_call.on_visible
- function="Self.ShowSitDown"/>
- <menu_item_call.on_enable
- function="Self.EnableSitDown" />
- </menu_item_call>
- <menu_item_call
- label="Stand Up"
- layout="topleft"
- shortcut="alt|shift|S"
- name="Stand up">
- <menu_item_call.on_click
- function="Self.StandUp"/>
- <menu_item_call.on_visible
- function="Self.EnableStandUp"/>
- <menu_item_call.on_enable
- function="Self.EnableStandUp" />
- </menu_item_call>
- <menu_item_check
- label="Fly"
- name="Fly"
- shortcut="HOME">
- <menu_item_check.on_check
- function="Agent.getFlying" />
- <menu_item_check.on_click
- function="Agent.toggleFlying" />
- <menu_item_check.on_enable
- function="Agent.enableFlying" />
- </menu_item_check>
- <menu_item_call
- label="Stop flying"
- name="Stop flying"
- shortcut="HOME">
- <menu_item_call.on_click
- function="Agent.toggleFlying" />
- <menu_item_call.on_enable
- function="Agent.getFlying" />
- </menu_item_call>
- <menu_item_check
- label="Always Run"
- name="Always Run"
- shortcut="control|R">
- <menu_item_check.on_check
- function="World.CheckAlwaysRun" />
- <menu_item_check.on_click
- function="World.AlwaysRun" />
- </menu_item_check>
- <menu_item_call
- label="Stop Animating Me"
- name="Stop Animating My Avatar">
- <menu_item_call.on_click
- function="Tools.StopAllAnimations" />
- </menu_item_call>
- <menu_item_call
- label="Walk / run / fly..."
- name="WalkRunFly">
- <menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="moveview" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Status"
- name="Status"
- tear_off="true">
- <menu_item_check
- name="Away"
- label="Away">
- <menu_item_check.on_check
- function="View.Status.CheckAway" />
- <menu_item_check.on_click
- function="World.SetAway" />
- </menu_item_check>
- <menu_item_check
- name="Do Not Disturb"
- label="Do Not Disturb">
- <menu_item_check.on_check
- function="View.Status.CheckDoNotDisturb" />
- <menu_item_check.on_click
- function="World.SetDoNotDisturb"/>
- </menu_item_check>
-
- </menu>
+ <menu_item_separator/>
+ <menu_item_check
+ name="Away"
+ label="Away">
+ <menu_item_check.on_check
+ function="View.Status.CheckAway" />
+ <menu_item_check.on_click
+ function="World.SetAway" />
+ </menu_item_check>
+ <menu_item_check
+ name="Do Not Disturb"
+ label="Do Not Disturb">
+ <menu_item_check.on_check
+ function="View.Status.CheckDoNotDisturb" />
+ <menu_item_check.on_click
+ function="World.SetDoNotDisturb"/>
+ </menu_item_check>
<menu_item_separator/>
@@ -210,6 +107,15 @@
name="ManageMyAccount_url"
parameter="WebLaunchJoinNow,http://secondlife.com/account/" />
</menu_item_call>
+ <menu_item_call
+ label="[Membership]"
+ name="Membership">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="https://secondlife.com/my/account/membership.php"/>
+ <menu_item_call.on_visible
+ function="Membership.UpdateLabel"/>
+ </menu_item_call>
<menu_item_separator/>
@@ -257,6 +163,334 @@
</menu>
<menu
create_jump_keys="true"
+ label="Avatar"
+ name="Avatar"
+ tear_off="true">
+ <menu_item_call
+ label="Now wearing..."
+ name="NowWearing"
+ shortcut="control|O">
+ <menu_item_call.on_click
+ function="NowWearing" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu_item_call
+ label="My outfits..."
+ name="ChangeOutfit">
+ <menu_item_call.on_click
+ function="CustomizeAvatar" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu_item_call label="Hover height..."
+ layout="topleft"
+ shortcut="alt|control|H"
+ name="Hover Height">
+ <menu_item_call.on_click
+ function="HoverHeight" />
+ <menu_item_call.on_enable
+ function="Edit.EnableHoverHeight" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit shape..."
+ layout="topleft"
+ name="Edit My Shape">
+ <menu_item_call.on_click
+ function="EditShape" />
+ <menu_item_call.on_enable
+ function="Edit.EnableEditShape" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit outfit parts..."
+ layout="topleft"
+ name="Edit Outfit">
+ <menu_item_call.on_click
+ function="EditOutfit" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu
+ label="Take off"
+ layout="topleft"
+ name="Take Off &gt;">
+ <menu
+ label="Clothes"
+ layout="topleft"
+ name="Clothes &gt;">
+ <menu_item_call
+ enabled="false"
+ label="Shirt"
+ layout="topleft"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Pants"
+ layout="topleft"
+ name="Pants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="pants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shoes" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Socks"
+ layout="topleft"
+ name="Socks">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="socks" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="jacket" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="gloves" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Undershirt"
+ layout="topleft"
+ name="Self Undershirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="undershirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Underpants"
+ layout="topleft"
+ name="Self Underpants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="underpants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Tattoo"
+ layout="topleft"
+ name="Self Tattoo">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="tattoo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Physics"
+ layout="topleft"
+ name="Self Physics">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="physics" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="physics" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Alpha"
+ layout="topleft"
+ name="Self Alpha">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="alpha" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="All Clothes"
+ layout="topleft"
+ name="All Clothes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="all" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="HUD"
+ layout="topleft"
+ name="Avatar Detach HUD" />
+ <menu
+ label="Detach"
+ layout="topleft"
+ name="Avatar Detach" />
+ <menu_item_call
+ label="Detach All"
+ layout="topleft"
+ name="Detach All">
+ <menu_item_call.on_click
+ function="Self.RemoveAllAttachments"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="Self.EnableRemoveAllAttachments" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator/>
+ <menu_item_call
+ label="Complete avatars..."
+ name="Avatar Picker">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="avatar" />
+ </menu_item_call>
+ <menu_item_separator/>
+
+ <menu_item_call
+ label="Sit / stand"
+ layout="topleft"
+ shortcut="alt|shift|S"
+ name="Sit stand">
+ <menu_item_call.on_click
+ function="Self.ToggleSitStand"/>
+ <menu_item_call.on_enable
+ function="Self.EnableSitStand" />
+ </menu_item_call>
+ <menu_item_call
+ label="Fly / land"
+ name="Fly land"
+ shortcut="HOME">
+ <menu_item_call.on_click
+ function="Agent.toggleFlying" />
+ <menu_item_call.on_enable
+ function="Agent.enableFlyLand" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop animations"
+ name="Stop Animating My Avatar">
+ <menu_item_call.on_click
+ function="Tools.StopAllAnimations" />
+ </menu_item_call>
+ <menu_item_check
+ label="Walk / run / fly..."
+ name="WalkRunFly">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="moveview" />
+ <menu_item_check.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="moveview" />
+ </menu_item_check>
+ <menu_item_check
+ label="Always run"
+ name="Always Run"
+ shortcut="control|R">
+ <menu_item_check.on_check
+ function="World.CheckAlwaysRun" />
+ <menu_item_check.on_click
+ function="World.AlwaysRun" />
+ </menu_item_check>
+ <menu_item_separator/>
+ <menu_item_check
+ label="Gestures..."
+ name="Gestures"
+ shortcut="control|G">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="gestures" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="gestures" />
+ </menu_item_check>
+ <menu_item_separator/>
+ <menu_item_call
+ label="Reset skeleton"
+ layout="topleft"
+ name="Reset Skeleton">
+ <menu_item_call.on_click
+ function="Avatar.ResetSkeleton" />
+ </menu_item_call>
+ <menu_item_call
+ label="Reset skeleton and animations"
+ layout="topleft"
+ name="Reset Skeleton And Animations">
+ <menu_item_call.on_click
+ function="Avatar.ResetSkeletonAndAnimations" />
+ </menu_item_call>
+ <menu_item_call
+ label="Attachment scripts..."
+ name="MyScripts">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="my_scripts"/>
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call
+ label="Help with avatars..."
+ name="Help with avatars">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="https://community.secondlife.com/search/?type=cms_records3&amp;tags=avatar&amp;nodes=30&amp;search_and_or=or"/>
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
label="Communicate"
name="Communicate"
tear_off="true">
@@ -455,10 +689,11 @@
</menu_item_check>
<menu_item_call
label="Events"
- name="Events">
+ name="Events"
+ shortcut="control|E">
<menu_item_call.on_click
function="Advanced.ShowURL"
- parameter="http://events.secondlife.com"/>
+ parameter="https://secondlife.com/my/community/events"/>
</menu_item_call>
<menu_item_check
label="Search..."
@@ -521,12 +756,18 @@
parameter="region_info" />
</menu_item_call>
<menu_item_call
- label="My land holdings..."
- name="My Land">
+ label="My Linden Home..."
+ name="Linden Home">
+ <menu_item_call.on_click
+ function="World.LindenHome"/>
+ </menu_item_call>
+ <menu_item_call
+ label="My land holdings..."
+ name="My Land">
<menu_item_call.on_click
function="Floater.Show"
parameter="land_holdings" />
- </menu_item_call>
+ </menu_item_call>
<menu_item_call
label="Buy this land"
name="Buy Land">
@@ -603,8 +844,7 @@
<menu_item_separator />
<menu_item_check
label="Advanced Menu"
- name="Show Advanced Menu"
- shortcut="control|alt|shift|D">
+ name="Show Advanced Menu">
<on_check
function="CheckControl"
parameter="UseDebugMenus" />
@@ -639,12 +879,13 @@
<menu
create_jump_keys="true"
- label="Sun"
- name="Sun"
+ label="Environment"
+ name="Environment"
tear_off="true">
<menu_item_check
label="Sunrise"
- name="Sunrise">
+ name="Sunrise"
+ shortcut="control|shift|O">
<menu_item_check.on_click
function="World.EnvSettings"
parameter="sunrise" />
@@ -676,7 +917,8 @@
</menu_item_check>
<menu_item_check
label="Midnight"
- name="Midnight">
+ name="Midnight"
+ shortcut="control|shift|Z">
<menu_item_check.on_click
function="World.EnvSettings"
parameter="midnight" />
@@ -684,10 +926,9 @@
function="World.EnableEnvSettings"
parameter="midnight" />
</menu_item_check>
- <menu_item_separator/>
<menu_item_check
- label="Use Region Settings"
- name="Use Region Settings">
+ label="Use Shared Environment"
+ name="Use Shared Environment">
<menu_item_check.on_click
function="World.EnvSettings"
parameter="region" />
@@ -695,113 +936,105 @@
function="World.EnableEnvSettings"
parameter="region" />
</menu_item_check>
- </menu>
-
-
+ <menu_item_separator/>
+ <menu_item_call
+ label="My Environments..."
+ name="my_environs">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="my_environs" />
+ </menu_item_call>
+
+<menu_item_call
+ label="Personal Lighting..."
+ name="adjustment_tool">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="adjust_tool" />
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_check
+ label="Pause Clouds"
+ name="pause_clouds">
+ <menu_item_check.on_click
+ function="World.EnvSettings"
+ parameter="pause_clouds" />
+ <menu_item_check.on_check
+ function="World.EnableEnvSettings"
+ parameter="pause_clouds" />
+ </menu_item_check>
+ </menu>
+
+<!--
<menu
create_jump_keys="true"
label="Environment Editor"
name="Environment Editor"
tear_off="true">
-
- <menu_item_call
+ <menu_item_call
label="Environment Settings..."
name="Environment Settings">
- <menu_item_call.on_click
+<menu_item_call.on_click
function="World.EnvSettings"
parameter="editor"/>
</menu_item_call>
-
- <menu_item_separator/>
-
- <menu
+ <menu_item_separator/>
+<menu
name="Water Presets"
label="Water Presets">
- <menu_item_call
- label="New preset..."
+<menu_item_call
+label="New preset..."
name="new_water_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="new_water"/>
- </menu_item_call>
- <menu_item_call
- label="Edit preset..."
+</menu_item_call>
+<menu_item_call
+label="Edit preset..."
name="edit_water_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="edit_water"/>
- </menu_item_call>
- <menu_item_call
- label="Delete preset..."
- name="delete_water_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
- parameter="delete_water"/>
- <menu_item_call.on_enable
- function="World.EnableEnvPreset"
- parameter="delete_water"/>
- </menu_item_call>
- </menu>
-
- <menu
- name="Sky Presets"
+</menu_item_call>
+</menu>
+ <menu
+name="Sky Presets"
label="Sky Presets">
- <menu_item_call
- label="New preset..."
+<menu_item_call
+label="New preset..."
name="new_sky_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="new_sky"/>
- </menu_item_call>
- <menu_item_call
- label="Edit preset..."
+</menu_item_call>
+<menu_item_call
+label="Edit preset..."
name="edit_sky_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="edit_sky"/>
- </menu_item_call>
- <menu_item_call
- label="Delete preset..."
- name="delete_sky_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
- parameter="delete_sky"/>
- <menu_item_call.on_enable
- function="World.EnableEnvPreset"
- parameter="delete_sky"/>
- </menu_item_call>
- </menu>
-
- <menu
- name="Day Presets"
+</menu_item_call>
+</menu>
+<menu
+name="Day Presets"
label="Day Presets">
- <menu_item_call
- label="New preset..."
+<menu_item_call
+label="New preset..."
name="new_day_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="new_day_cycle"/>
- </menu_item_call>
- <menu_item_call
- label="Edit preset..."
+</menu_item_call>
+<menu_item_call
+label="Edit preset..."
name="edit_day_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
+<menu_item_call.on_click
+function="World.EnvPreset"
parameter="edit_day_cycle"/>
- </menu_item_call>
- <menu_item_call
- label="Delete preset..."
- name="delete_day_preset">
- <menu_item_call.on_click
- function="World.EnvPreset"
- parameter="delete_day_cycle"/>
- <menu_item_call.on_enable
- function="World.EnableEnvPreset"
- parameter="delete_day_cycle"/>
- </menu_item_call>
- </menu>
- </menu>
-
+</menu_item_call>
+</menu>
+</menu>
+-->
</menu>
<menu
@@ -1031,8 +1264,7 @@
shortcut="control|D">
<menu_item_call.on_click
function="Object.Duplicate" />
-
- </menu_item_call>
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -1293,7 +1525,7 @@
function="File.EnableUpload" />
<menu_item_call.on_visible
function="Upload.CalculateCosts"
- parameter="Upload Image" />
+ parameter="Upload Image,texture" />
</menu_item_call>
<menu_item_call
label="Sound (L$[COST])..."
@@ -1306,7 +1538,7 @@
function="File.EnableUpload" />
<menu_item_call.on_visible
function="Upload.CalculateCosts"
- parameter="Upload Sound" />
+ parameter="Upload Sound,sound" />
</menu_item_call>
<menu_item_call
label="Animation (L$[COST])..."
@@ -1319,12 +1551,13 @@
function="File.EnableUpload" />
<menu_item_call.on_visible
function="Upload.CalculateCosts"
- parameter="Upload Animation" />
+ parameter="Upload Animation,animation" />
</menu_item_call>
<menu_item_call
label="Model..."
layout="topleft"
- name="Upload Model">
+ name="Upload Model"
+ shortcut="alt|control|U">
<menu_item_call.on_click
function="File.UploadModel"
parameter="" />
@@ -1334,9 +1567,12 @@
function="File.VisibleUploadModel"/>
</menu_item_call>
<menu_item_call
- label="Bulk (L$[COST] per file)..."
+ label="Bulk..."
layout="topleft"
name="Bulk Upload">
+ <menu_item_call.on_visible
+ function="Upload.CalculateCosts"
+ parameter="Bulk Upload,texture" />
<menu_item_call.on_click
function="File.UploadBulk"
parameter="" />
@@ -1374,20 +1610,13 @@
name="Help"
tear_off="true">
<menu_item_call
- label="How to..."
+ label="Guidebook"
name="How To"
shortcut="F1">
<menu_item_call.on_click
function="Help.ToggleHowTo"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Quickstart"
- name="Quickstart">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/>
- </menu_item_call>
<!-- <menu_item_call
label="Tutorial"
name="Tutorial">
@@ -1737,6 +1966,16 @@
parameter="character" />
</menu_item_check>
<menu_item_check
+ label="Animeshes"
+ name="Rendering Type Control Avatar">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="controlAV" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="controlAV" />
+ </menu_item_check>
+ <menu_item_check
label="Surface Patch"
name="Rendering Type Surface Patch"
shortcut="control|alt|shift|5">
@@ -1976,20 +2215,6 @@
name="Shortcuts"
tear_off="true"
visible="false">
- <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility. The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. -->
- <menu_item_check
- label="Show Advanced Menu - legacy shortcut"
- name="Show Advanced Menu - legacy shortcut"
- shortcut="control|alt|D">
- <on_check
- function="CheckControl"
- parameter="UseDebugMenus" />
- <on_click
- function="ToggleControl"
- parameter="UseDebugMenus" />
- </menu_item_check>
-
- <menu_item_separator/>
<menu_item_call
label="Close Window"
@@ -2936,6 +3161,36 @@
parameter="TextureDisable" />
</menu_item_check>
<menu_item_check
+ label="Disable Ambient"
+ name="Disable Ambient">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AmbientDisable" />
+ <menu_item_check.on_click
+ function="ToggleShaderControl"
+ parameter="AmbientDisable" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Sunlight"
+ name="Disable Sunlight">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SunlightDisable" />
+ <menu_item_check.on_click
+ function="ToggleShaderControl"
+ parameter="SunlightDisable" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Local Lights"
+ name="Disable Local Lights">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="LocalLightDisable" />
+ <menu_item_check.on_click
+ function="ToggleShaderControl"
+ parameter="LocalLightDisable" />
+ </menu_item_check>
+ <menu_item_check
label="Full Res Textures"
name="Rull Res Textures">
<menu_item_check.on_check
@@ -3585,7 +3840,7 @@
<menu_item_call
label="Debug Avatar Textures"
name="Debug Avatar Textures"
- shortcut="control|alt|shift|A">
+ shortcut="control|alt|shift|K">
<menu_item_call.on_click
function="Advanced.DebugAvatarTextures" />
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
index aa56b4ba63..20c81c983b 100644
--- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
@@ -4,6 +4,7 @@
<menu_item_call
label="Replace"
layout="topleft"
+ visible="false"
name="wear_replace">
<on_click
function="Wearable.Wear" />
@@ -11,6 +12,7 @@
<menu_item_call
label="Wear"
layout="topleft"
+ visible="false"
name="wear_wear">
<on_click
function="Wearable.Wear" />
@@ -18,13 +20,29 @@
<menu_item_call
label="Add"
layout="topleft"
+ visible="false"
name="wear_add">
<on_click
function="Wearable.Add" />
</menu_item_call>
<menu_item_call
+ label="Touch"
+ layout="topleft"
+ name="touch"
+ visible="false"
+ on_click.function="Attachment.Touch"
+ />
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit"
+ visible="false"
+ on_click.function="Wearable.Edit"
+ />
+ <menu_item_call
label="Take Off / Detach"
layout="topleft"
+ visible="false"
name="take_off_or_detach">
<on_click
function="Wearable.TakeOffDetach" />
@@ -32,6 +50,7 @@
<menu_item_call
label="Detach"
layout="topleft"
+ visible="false"
name="detach">
<on_click
function="Attachment.Detach" />
@@ -47,20 +66,15 @@
<menu_item_call
label="Take Off"
layout="topleft"
+ visible="false"
name="take_off">
<on_click
function="Clothing.TakeOff" />
</menu_item_call>
<menu_item_call
- label="Edit"
- layout="topleft"
- name="edit">
- <on_click
- function="Wearable.Edit" />
- </menu_item_call>
- <menu_item_call
label="Item Profile"
layout="topleft"
+ visible="false"
name="object_profile">
<on_click
function="Attachment.Profile" />
@@ -68,6 +82,7 @@
<menu_item_call
label="Show Original"
layout="topleft"
+ visible="false"
name="show_original">
<on_click
function="Wearable.ShowOriginal" />
@@ -75,6 +90,7 @@
<menu_item_call
label="Create New"
layout="topleft"
+ visible="false"
name="create_new"
translate="false">
<on_click
@@ -83,6 +99,7 @@
<menu_item_call
label="--no options--"
layout="topleft"
+ visible="false"
name="--no options--"
translate="false">
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
index 0e858ccf10..57b20dfda9 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
@@ -4,11 +4,24 @@
visible="false"
name="Gear Wearing">
<menu_item_call
- label="Edit Outfit"
+ label="Touch"
+ layout="topleft"
+ name="touch">
+ <on_click
+ function="Gear.TouchAttach" />
+ <on_enable
+ function="Gear.OnEnable"
+ parameter="touch_attach" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
layout="topleft"
- name="edit">
+ name="edit_item">
<on_click
- function="Gear.Edit" />
+ function="Gear.EditItem" />
+ <on_enable
+ function="Gear.OnEnable"
+ parameter="edit_item" />
</menu_item_call>
<menu_item_call
label="Take Off"
@@ -20,6 +33,14 @@
function="Gear.OnEnable"
parameter="take_off" />
</menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="Edit Outfit"
+ layout="topleft"
+ name="edit_outfit">
+ <on_click
+ function="Gear.EditOutfit" />
+ </menu_item_call>
<menu_item_call
label="Copy outfit list to clipboard"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
index 75c1de24aa..b8e2b44884 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
@@ -3,6 +3,20 @@
layout="topleft"
name="Wearing">
<menu_item_call
+ label="Touch"
+ layout="topleft"
+ name="touch_attach">
+ <on_click
+ function="Wearing.TouchAttach" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ layout="topleft"
+ name="edit_item">
+ <on_click
+ function="Wearing.EditItem" />
+ </menu_item_call>
+ <menu_item_call
label="Take Off"
layout="topleft"
name="take_off">
@@ -23,16 +37,9 @@
<menu_item_call
label="Edit Outfit"
layout="topleft"
- name="edit">
+ name="edit_outfit">
<on_click
- function="Wearing.Edit" />
- </menu_item_call>
- <menu_item_call
- label="Edit"
- layout="topleft"
- name="edit_item">
- <on_click
- function="Wearing.EditItem" />
+ function="Wearing.EditOutfit" />
</menu_item_call>
<menu_item_call
label="Show Original"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index af9602ea11..4a02b576c2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -686,6 +686,18 @@ Do you want to revoke modify rights for the selected Residents?
<notification
icon="alertmodal.tga"
+ name="GroupNameLengthWarning"
+ type="alertmodal">
+A group name must be between [MIN_LEN] and [MAX_LEN] characters.
+ <tag>group</tag>
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="UnableToCreateGroup"
type="alertmodal">
Unable to create group.
@@ -920,7 +932,7 @@ You do not have enough L$ to join this group.
icon="alertmodal.tga"
name="CreateGroupCost"
type="alertmodal">
-Creating this group will cost L$100.
+Creating this group will cost L$[COST].
Groups need more than one member, or they are deleted forever.
Please invite members within 48 hours.
<tag>group</tag>
@@ -929,7 +941,7 @@ Please invite members within 48 hours.
canceltext="Cancel"
name="okcancelbuttons"
notext="Cancel"
- yestext="Create group for L$100"/>
+ yestext="Create group for L$[COST]"/>
</notification>
<notification
@@ -1012,18 +1024,6 @@ The group no longer has open enrollment.
<notification
icon="alertmodal.tga"
- name="JoinGroupSuccess"
- type="alertmodal">
-You have been added to the group
- <tag>group_id</tag>
- <tag>success</tag>
- <usetemplate
- name="okbutton"
- yestext="OK"/>
- </notification>
-
- <notification
- icon="alertmodal.tga"
name="JoinGroupInsufficientFunds"
type="alertmodal">
Unable to transfer the required L$ [membership_fee] membership fee.
@@ -1291,6 +1291,14 @@ Error encoding snapshot.
<notification
icon="alertmodal.tga"
+ name="ErrorCannotAffordUpload"
+ type="alertmodal">
+ You need L$[COST] to upload this item.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ErrorTextureCannotAfford"
type="alertmodal">
You need L$[COST] to save a texture to your inventory. You may either buy L$ or save the photo to your computer instead.
@@ -1323,6 +1331,18 @@ You must agree to the Second Life Terms and Conditions, Privacy Policy, and Term
<notification
icon="alertmodal.tga"
+ name="CouldNotBuyCurrency"
+ type="alertmodal">
+[TITLE]
+[MESSAGE]
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CouldNotPutOnOutfit"
type="alertmodal">
Could not put on outfit.
@@ -1493,7 +1513,7 @@ Go to the [SECOND_LIFE] events web page?
<tag>confirm</tag>
<url option="0" name="url">
- http://secondlife.com/events/
+ https://secondlife.com/my/community/events
</url>
<usetemplate
name="okcancelbuttons"
@@ -2180,7 +2200,7 @@ Wrong chunk size in WAV file:
icon="alertmodal.tga"
name="SoundFileInvalidTooLong"
type="alertmodal">
-Audio file is too long (10 second maximum):
+Audio file is too long (30 second maximum):
[FILE]
<tag>fail</tag>
</notification>
@@ -2259,6 +2279,7 @@ Unable to create output file: [FILE]
icon="alertmodal.tga"
name="DoNotSupportBulkAnimationUpload"
type="alertmodal">
+ <unique/>
[APP_NAME] does not currently support bulk upload of BVH format animation files.
<tag>fail</tag>
</notification>
@@ -2299,6 +2320,29 @@ You cannot create a landmark here because the owner of the land doesn&apos;t all
</notification>
<notification
+ icon="alertmodal.tga"
+ label="Create folder"
+ name="CreateLandmarkFolder"
+ type="alertmodal">
+ <unique/>
+ Choose a name for the folder:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="CannotRecompileSelectObjectsNoScripts"
type="alertmodal">
@@ -2410,9 +2454,8 @@ Teleport failed.
icon="alertmodal.tga"
name="invalid_tport"
type="alertmodal">
-Problem encountered processing your teleport request. You may need to log back in before you can teleport.
-If you continue to get this message, please check the [SUPPORT_SITE].
- <tag>fail</tag>
+Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again.
+ <tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
@@ -3120,7 +3163,30 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
text="Cancel"/>
</form>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ label="Rename Landmark"
+ name="RenameLandmark"
+ type="alertmodal">
+ Choose a new name for [NAME]
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="new_name" type="text" width="300">
+ [NAME]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="RemoveFromFriends"
@@ -3153,7 +3219,7 @@ Do you want to remove multiple friends from your Friends list?
type="alertmodal">
Are you sure you want to delete all scripted objects owned by
** [AVATAR_NAME] **
-on all others land in this sim?
+on all others land in this region?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3167,7 +3233,7 @@ on all others land in this sim?
type="alertmodal">
Are you sure you want to DELETE ALL scripted objects owned by
** [AVATAR_NAME] **
-on ALL LAND in this sim?
+on ALL LAND in this region?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3181,7 +3247,7 @@ on ALL LAND in this sim?
type="alertmodal">
Are you sure you want to DELETE ALL objects (scripted or not) owned by
** [AVATAR_NAME] **
-on ALL LAND in this sim?
+on ALL LAND in this region?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3440,6 +3506,9 @@ Display settings have been set to recommended levels because of a change to the
icon="alertmodal.tga"
name="ErrorMessage"
type="alertmodal">
+ <unique>
+ <context>ERROR_MESSAGE</context>
+ </unique>
[ERROR_MESSAGE]
<tag>fail</tag>
<usetemplate
@@ -3548,6 +3617,26 @@ If this is your first time using [SECOND_LIFE], you will need to create an accou
<notification
icon="alertmodal.tga"
+ name="LoginCantRemoveUsername"
+ type="alertmodal">
+ <tag>fail</tag>
+Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LoginCantRemoveCurUsername"
+ type="alertmodal">
+ <tag>confirm</tag>
+Forgetting the logged-in user requires you to log out.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Confirm and log out"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="LoginPacketNeverReceived"
type="alertmodal">
<tag>fail</tag>
@@ -3601,6 +3690,18 @@ You can either check your Internet connection and try again in a few minutes or
<notification
icon="alertmodal.tga"
+ name="LoginRemoveMultiGridUserData"
+ type="alertmodal">
+ <tag>confirm</tag>
+Local Data you are deleting is shared between multiple grids, are you sure you want to delete it?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Confirm"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="WelcomeChooseSex"
type="alertmodal">
Your character will appear in a moment.
@@ -3624,6 +3725,17 @@ Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the curr
</notification>
<notification icon="alertmodal.tga"
+ name="GeneralCertificateErrorShort"
+ type="alertmodal">
+Could not connect to the server.
+[REASON]
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification icon="alertmodal.tga"
name="GeneralCertificateError"
type="alertmodal">
Could not connect to the server.
@@ -3960,6 +4072,8 @@ Finished download of raw terrain file to:
[DOWNLOAD_PATH].
</notification>
+ <!-- RequiredUpdate does not display release notes URL because we don't get
+ that from login.cgi's login failure message. -->
<notification
icon="alertmodal.tga"
name="RequiredUpdate"
@@ -3977,6 +4091,8 @@ Please download from https://secondlife.com/support/downloads/
name="PauseForUpdate"
type="alertmodal">
Version [VERSION] is required for login.
+Release notes: [URL]
+
Click OK to download and install.
<tag>confirm</tag>
<usetemplate
@@ -3989,6 +4105,8 @@ Click OK to download and install.
name="OptionalUpdateReady"
type="alertmodal">
Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
Click OK to install.
<tag>confirm</tag>
<usetemplate
@@ -4001,6 +4119,8 @@ Click OK to install.
name="PromptOptionalUpdate"
type="alertmodal">
Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
Proceed?
<tag>confirm</tag>
<usetemplate
@@ -4170,13 +4290,6 @@ Leave Group?
yestext="OK"/>
</notification>
- <notification
- icon="notify.tga"
- name="GroupDepart"
- type="notify">
-You have left the group &apos;&lt;nolink&gt;[group_name]&lt;/nolink&gt;&apos;.
- <tag>group</tag>
- </notification>
<notification
icon="alertmodal.tga"
@@ -4322,11 +4435,21 @@ You have reached your maximum number of groups. Please leave some group before j
icon="alert.tga"
name="GroupLimitInfo"
type="alert">
-The group limit for base accounts is [MAX_BASIC], and for [https://secondlife.com/premium/ premium]
-accounts is [MAX_PREMIUM].
-If you downgraded your account, you will need to get below [MAX_BASIC] group limit before you can join more.
+Residents with Basic memberships may join up to [MAX_BASIC] groups.
+Premium memberships allow up to [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Learn more or upgrade]
+ <tag>group</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="Close"/>
+ </notification>
-[https://secondlife.com/my/account/membership.php Upgrade today!]
+ <notification
+ icon="alert.tga"
+ name="GroupLimitInfoPlus"
+ type="alert">
+Residents with Basic memberships may join up to [MAX_BASIC] groups.
+Premium memberships allow up to [MAX_PREMIUM]. Premium Plus
+memberships allow up to [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Learn more or upgrade]
<tag>group</tag>
<usetemplate
name="okbutton"
@@ -4952,10 +5075,26 @@ Unchecking this option may remove restrictions that parcel owners have added to
<notification
icon="alertmodal.tga"
+ name="EstateParcelEnvironmentOverride"
+ type="alertmodal">
+(Estate-wide change: [ESTATENAME]) Unchecking this option will remove any custom environments that parcel owners have added to their parcels. Please discuss with your parcel owners as needed.
+Do you wish to proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+
+ <notification
+ icon="alertmodal.tga"
name="RegionEntryAccessBlocked"
type="alertmodal">
<tag>fail</tag>
- The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -5042,7 +5181,9 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
name="TeleportEntryAccessBlocked"
type="alertmodal">
<tag>fail</tag>
- The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -5191,6 +5332,8 @@ You won't receive any more notifications that you're about to visit a region wit
name="LandClaimAccessBlocked"
type="alertmodal">
The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
<tag>fail</tag>
<usetemplate
name="okbutton"
@@ -5260,6 +5403,8 @@ You won't receive any more notifications that you're about to visit a region wit
name="LandBuyAccessBlocked"
type="alertmodal">
The land you're trying to buy has a maturity rating exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
<tag>fail</tag>
<usetemplate
name="okbutton"
@@ -6053,6 +6198,34 @@ Would you like to turn off Do Not Disturb before completing this transaction?
</notification>
<notification
+ icon="notify.tga"
+ label="Parcel is Playing Media"
+ name="ParcelPlayingMedia"
+ persist="false"
+ type="notify">
+This location plays media:
+[URL]
+Would you like to play it?
+ <tag>confirm</tag>
+ <form name="form">
+ <ignore name="ignore"
+ checkbox_only="true"
+ text="Always choose this option for this land."/>
+ <button
+ ignore="Play Media"
+ index="1"
+ name="Yes"
+ text="Play"/>
+ <button
+ default="true"
+ ignore="Ignore Media"
+ index="0"
+ name="No"
+ text="Don't play"/>
+ </form>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="ConfirmDeleteProtectedCategory"
type="alertmodal">
@@ -6164,6 +6337,20 @@ Are you sure you want to permanently delete the contents of your Lost And Found?
<notification
icon="alertmodal.tga"
+ name="ConfirmReplaceLink"
+ type="alertmodal">
+You're about to replace '[TYPE]' body part link with the item which doesn't match the type.
+Are you sure you want to proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I replace link"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CopySLURL"
type="alertmodal">
The following SLurl has been copied to your clipboard:
@@ -6209,7 +6396,23 @@ This day cycle file references a missing sky file: [SKY].
icon="alertmodal.tga"
name="WLRegionApplyFail"
type="alertmodal">
-Sorry, the settings couldn't be applied to the region. Leaving the region and then returning may help rectify the problem. The reason given was: [FAIL_REASON]
+Sorry, the settings couldn't be applied to the region. Reason: [FAIL_REASON]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLLocalTextureDayBlock"
+ type="alertmodal">
+A Local texture is in use on track [TRACK], frame #[FRAMENO] ([FRAME]%) in field [FIELD].
+Settings may not be saved using local textures.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WLLocalTextureFixedBlock"
+ type="alertmodal">
+A local texture is in use in field [FIELD].
+Settings may not be saved using local textures.
</notification>
<notification
@@ -7066,12 +7269,16 @@ You can only claim public land in the Region you&apos;re in.
</notification>
<notification
- icon="notify.tga"
+ icon="alertmodal.tga"
name="RegionTPAccessBlocked"
- persist="false"
- type="notify">
+ type="alertmodal">
<tag>fail</tag>
- The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
</notification>
<notification
@@ -8396,6 +8603,18 @@ Can not overwrite default preset.
</notification>
<notification
+ icon="alertmodal.tga"
+ name="PresetAlreadyExists"
+ type="alertmodal">
+&apos;[NAME]&apos; is in use. You may replace
+this preset or choose another name.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
icon="notifytip.tga"
name="PresetNotDeleted"
type="notifytip">
@@ -8442,9 +8661,50 @@ Your voice has been muted by moderator.
name="okbutton"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedToGetBenefits"
+ type="alertmodal">
+ Unfortunately, we were unable to get benefits information for this session. This should not happen in a normal production environment. Please contact support. This session will not work normally and we recommend that you restart.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BulkUploadCostConfirmation"
+ type="alertmodal">
+This will upload [COUNT] items at a total cost of L$[COST]. Do you wish to continue with the upload?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Upload"/>
+ </notification>
<notification
icon="alertmodal.tga"
+ name="BulkUploadNoCompatibleFiles"
+ type="alertmodal">
+Selected files can not be bulk-uploaded.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BulkUploadIncompatibleFiles"
+ type="alertmodal">
+Some of the selected files can not be bulk-uploaded.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="UploadCostConfirmation"
type="alertmodal">
This upload will cost L$[PRICE], do you wish to continue with the upload?
@@ -8458,7 +8718,7 @@ This upload will cost L$[PRICE], do you wish to continue with the upload?
icon="alertmodal.tga"
name="ConfirmClearTeleportHistory"
type="alertmodal">
-Are you sure you want to delete your teleport history?
+This will delete the entire list of places you have visited, and cannot be undone. Continue?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -9352,12 +9612,24 @@ Do you wish to continue?
yestext="OK"/>
</notification>
+ <global name="UnsupportedShaderRequirements">
+You do not appear to meet the hardware requirements for [APP_NAME]. [APP_NAME] requires OpenGL 2.0 or later shader support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
+
+If you continue to have problems, please visit the [SUPPORT_SITE].
+ </global>
+
<global name="UnsupportedGLRequirements">
You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
If you continue to have problems, please visit the [SUPPORT_SITE].
</global>
+ <global name="UnsupportedIntelDriver">
+The installed Intel graphics driver for [GPUNAME], version [VERSION], is significantly out of date and is known to cause excessive rates of program crashes. You are strongly advised to update to a current Intel driver
+
+Do you want to check the Intel driver website?
+ </global>
+
<global name="UnsupportedCPUAmount">
796
</global>
@@ -9373,6 +9645,10 @@ If you continue to have problems, please visit the [SUPPORT_SITE].
<global name="UnsupportedRAM">
- Your system memory does not meet the minimum requirements.
</global>
+
+ <global name="LLLeapUpdaterFailure">
+Failed to launch updater service [UPDATER_APP]. Please verify the viewer is installed correctly and has the necessary permissions to run. If you continue to experience issues, please visit the [SUPPORT_SITE].
+ </global>
<!-- these are alert strings from server. the name needs to match entire the server string, and needs to be changed
whenever the server string changes -->
@@ -10074,7 +10350,7 @@ Unable to add script!
name="AssetServerTimeoutObjReturn"
type="notify">
<tag>fail</tag>
-Asset server didn't respond in a timely fashion. Object returned to sim.
+Asset server didn't respond in a timely fashion. Object returned to the region.
</notification>
<notification
@@ -11215,6 +11491,19 @@ Cannot create large prims that intersect other residents. Please re-try when ot
notext="Cancel"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PreferenceControlsDefaults"
+ type="alertmodal">
+ Do you want to restore default values for controls?
+ <tag>confirm</tag>
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Current mode"
+ yestext="All modes"/>
+ </notification>
<notification
icon="alertmodal.tga"
@@ -11260,7 +11549,28 @@ Cannot create large prims that intersect other residents. Please re-try when ot
name="okbutton"
yestext="OK"/>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="AddPaymentMethod"
+ type="alertmodal">
+On the following page, choose a L$ amount
+and click a place Order button. You will be
+able to add a payment method at checkout.
+ <tag>confirm</tag>
+ <form name="form">
+ <button
+ default="true"
+ index="0"
+ width="120"
+ name="Continue"
+ text="Continue"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
<notification
icon="alert.tga"
@@ -11273,4 +11583,190 @@ Cannot create large prims that intersect other residents. Please re-try when ot
yestext="OK"/>
</notification>
+ <notification
+ icon="notify.tga"
+ name="FailedToFindSettings"
+ persist="true"
+ type="alertmodal">
+Could not load the settings for [NAME] from the database.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FailedToLoadSettingsApply"
+ persist="true"
+ type="alertmodal">
+Unable to apply those settings to the environment.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="FailedToBuildSettingsDay"
+ persist="true"
+ type="alertmodal">
+Unable to apply those settings to the environment.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoEnvironmentSettings"
+ persist="true"
+ type="alertmodal">
+This Region does not support environmental settings.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Save Outfit"
+ name="SaveSettingAs"
+ type="alertmodal">
+ <unique/>
+ Save current environmental settings as:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC] (new)
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="WLImportFail"
+ persist="true"
+ type="alertmodal">
+Unable to import legacy Windlight settings [NAME] from
+[FILE].
+
+[REASONS]
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="WLParcelApplyFail"
+ persist="true"
+ type="alertmodal">
+Unable to set the environment for this parcel.
+Please enter or select a parcel that you have rights to modify.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="SettingsUnsuported"
+ persist="true"
+ type="alertmodal">
+Settings are not supported on this region.
+Please move to a settings enabled region and retry your action.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SettingsConfirmLoss"
+ type="alertmodal">
+You are about to lose the changes you have made to this [TYPE] named "[NAME]".
+Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Are you sure you want to lose changes?"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SettingsConfirmReset"
+ type="alertmodal">
+You are about to remove all applied settings.
+Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PersonalSettingsConfirmReset"
+ type="alertmodal">
+You are about to remove all applied Personal lighting settings.
+Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SettingsMakeNoTrans"
+ type="alertmodal">
+You are about to import non-transferable settings into this daycycle. Continuing will cause the settings you are editing to become non-transferable also.
+
+This change can not be undone.
+
+Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Are you sure you want to make settings non-transferable?"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="NoEditFromLibrary"
+ persist="true"
+ type="alertmodal">
+You may not edit settings directly from the libary.
+Please copy to your own inventory and try again.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="EnvironmentApplyFailed"
+ persist="true"
+ type="alertmodal">
+We have encountered an issue with these settings. They can not be saved or applied at this time.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TrackLoadFailed"
+ persist="true"
+ type="alertmodal">
+Unable to load the track into [TRACK].
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TrackLoadMismatch"
+ persist="true"
+ type="alertmodal">
+Unable to load the track from [TRACK1] into [TRACK2].
+ <tag>fail</tag>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml b/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml
new file mode 100644
index 0000000000..9417ab4ac2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_camera_preset_item.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="camera_preset_item"
+ top="0"
+ width="280">
+ <icon
+ follows="top|right|left"
+ height="20"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ height="20"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <text
+ follows="left"
+ height="20"
+ layout="topleft"
+ left="10"
+ parse_urls="false"
+ use_ellipses="true"
+ name="preset_name"
+ text_color="White"
+ top="2"
+ value="Default"
+ width="159" />
+ <button
+ follows="right"
+ image_selected="TrashItem_Off"
+ image_pressed="TrashItem_Off"
+ image_unselected="TrashItem_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ right="-10"
+ name="delete_btn"
+ tool_tip="Delete preset"
+ top="3"
+ height="18"
+ width="18" >
+ <button.commit_callback
+ function="CameraPresets.Delete"/>
+ </button>
+ <button
+ follows="right"
+ image_selected="Refresh_Off"
+ image_pressed="Refresh_Off"
+ image_unselected="Refresh_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ right="-10"
+ name="reset_btn"
+ tool_tip="Reset preset to default"
+ top="2"
+ height="20"
+ width="20" >
+ <button.commit_callback
+ function="CameraPresets.Reset"/>
+ </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
index 27c653bc35..d1175a9fe1 100644
--- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
@@ -32,7 +32,6 @@
width="308"/>
<texture_picker
allow_no_texture="true"
- border_enabled="true"
fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 3509eaa285..e846edf1d4 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -144,7 +144,6 @@
follows="left|top|right"
height="100"
width="273"
- hide_scrollbar="false"
layout="topleft"
left="10"
top_pad="2"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 553c112e6f..357a5559bf 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -26,7 +26,7 @@
name="back_btn"
left="10"
tab_stop="false"
- top="2"
+ top="4"
width="30"
use_draw_context_alpha="false" />
<text
@@ -39,17 +39,17 @@
left_pad="4"
name="title"
text_color="LtGray"
- top="2"
+ top="4"
width="250">
Edit Pick
</text>
<scroll_container
color="DkGray2"
follows="all"
- height="502"
+ height="501"
layout="topleft"
left="8"
- top_pad="10"
+ top_pad="9"
name="profile_scroll"
opaque="true"
width="312">
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index dc1553e6a3..85d73ece48 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -13,7 +13,7 @@
width="333">
<string
name="edit_shape_title">
- Editing Shape
+ Shape
</string>
<string
name="edit_skin_title">
diff --git a/indra/newview/skins/default/xui/en/panel_favorites.xml b/indra/newview/skins/default/xui/en/panel_favorites.xml
new file mode 100644
index 0000000000..1e8ea34ad2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_favorites.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="Favorites"
+ layout="topleft"
+ left="0"
+ border="false"
+ background_visible="true"
+ bg_alpha_color="DkGray"
+ follows="all">
+ <places_inventory_panel
+ allow_multi_select="true"
+ border="false"
+ top="1"
+ left="3"
+ bottom="0"
+ follows="all"
+ right="-3"
+ mouse_opaque="true"
+ name="favorites_list"
+ folder_view.use_ellipses="true"
+ start_folder.name="Favorites"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml
new file mode 100644
index 0000000000..c0265c2fa2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_creation_sidetray.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+background_visible="true"
+ follows="all"
+ height="570"
+ label="Group Creation"
+ layout="topleft"
+ min_height="350"
+ left="0"
+ top="20"
+ name="GroupCreation"
+ width="313">
+ <panel.string
+ name="current_membership">
+(your membership)
+ </panel.string>
+ <panel
+ name="group_info_top"
+ follows="top|left"
+ top="0"
+ left="0"
+ height="29"
+ width="313"
+ layout="topleft">
+ <line_editor
+ follows="left|top"
+ font="SansSerif"
+ label="Type your new group name here"
+ layout="topleft"
+ max_length_bytes="35"
+ name="group_name_editor"
+ left="12"
+ top="5"
+ width="270"
+ height="20"
+ visible="true" />
+ </panel>
+ <layout_stack
+ name="layout"
+ orientation="vertical"
+ follows="all"
+ left="8"
+ top_pad="0"
+ height="538"
+ width="300"
+ border_size="0">
+ <layout_panel
+ bg_alpha_color="DkGray2"
+ bg_opaque_color="DkGray2"
+ background_visible="true"
+ background_opaque="true"
+ name="group_info"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ user_resize="false"
+ height="206"
+ width="313">
+ <panel
+ name="group_info_top"
+ follows="top|left|right"
+ top="0"
+ left="0"
+ height="99"
+ width="312"
+ layout="topleft">
+ <texture_picker
+ default_image_name="Generic_Group_Large"
+ follows="left|top"
+ name="insignia"
+ label=""
+ no_commit_on_selection="true"
+ tool_tip="Click to choose a picture"
+ layout="topleft"
+ height="110"
+ left="5"
+ top="5"
+ width="100" />
+ <text_editor
+ follows="left|top|right"
+ layout="topleft"
+ type="string"
+ name="charter"
+ left_pad="3"
+ height="86"
+ max_length="511"
+ top="6"
+ right="-4"
+ bg_readonly_color="DkGray2"
+ text_readonly_color="White"
+ word_wrap="true">
+ Group Charter
+ </text_editor>
+ </panel>
+ <panel
+ layout="topleft"
+ follows="left|top|right"
+ background_visible="false"
+ bevel_style="none"
+ border="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
+ height="100"
+ width="313"
+ left="0"
+ name="preferences_container"
+ top_pad="5">
+ <check_box
+ follows="right|top|left"
+ layout="topleft"
+ label="Anyone can join"
+ height="16"
+ left="10"
+ name="open_enrollement"
+ tool_tip="Sets whether this group allows new members to join without being invited."
+ width="90" />
+ <check_box
+ label="Cost to join"
+ layout="topleft"
+ name="check_enrollment_fee"
+ tool_tip="Sets whether to require an enrollment fee to join the group"
+ top_pad="5"
+ left_delta="0"
+ height="16"
+ width="300" />
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ halign="left"
+ increment="1"
+ label_width="15"
+ label="L$"
+ layout="topleft"
+ max_val="99999"
+ height="23"
+ left="30"
+ name="spin_enrollment_fee"
+ tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."
+ width="170" />
+ <combo_box
+ follows="left|top"
+ layout="topleft"
+ name="group_mature_check"
+ tool_tip="Maturity ratings designate the type of content and behavior allowed in a group"
+ height="23"
+ left="10"
+ top_pad="4"
+ width="190">
+ <combo_item name="select_mature" value="Select">
+ - Select maturity rating -
+ </combo_item>
+ <combo_box.item
+ label="Moderate Content"
+ name="mature"
+ value="Mature" />
+ <combo_box.item
+ label="General Content"
+ name="pg"
+ value="Not Mature" />
+ </combo_box>
+ </panel>
+ </layout_panel>
+ <layout_panel
+ background_visible="false"
+ background_opaque="true"
+ name="create_info"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ user_resize="false"
+ height="200"
+ width="313">
+ <text
+ font="SansSerifSmall"
+ follows="top|left|right"
+ layout="topleft"
+ mouse_opaque="false"
+ type="string"
+ name="fee_information"
+ skip_link_underline="true"
+ height="26"
+ left="8"
+ right="-8"
+ top="5"
+ word_wrap="true">
+ The fee to create a group is based on your membership level. [https://secondlife.com/my/account/membership.php More info]
+ </text>
+ <scroll_list
+ draw_border="false"
+ background_visible="false"
+ follows="left|top|bottom|right"
+ layout="topleft"
+ multi_select="true"
+ name="membership_list"
+ row_padding="4"
+ enabled="false"
+ height="150"
+ left="2"
+ top_pad="8"
+ width="290">
+ <scroll_list.columns
+ dynamic_width="false"
+ name="clmn_name"
+ width="220"/>
+ <scroll_list.columns
+ dynamic_width="true"
+ name="clmn_price"/>
+ <scroll_list.rows
+ name="basic"
+ value="Basic (placeholder)"/>
+ <scroll_list.rows
+ name="plc2"
+ value="" />
+ <scroll_list.rows
+ name="premium"
+ value="Premium (placeholder)" />
+ </scroll_list>
+ </layout_panel>
+ <layout_panel
+ background_visible="false"
+ background_opaque="true"
+ name="create_actions"
+ follows="all"
+ layout="topleft"
+ auto_resize="true"
+ user_resize="true"
+ height="200"
+ width="313">
+ </layout_panel>
+ <layout_panel
+ background_visible="false"
+ background_opaque="true"
+ name="create_actions"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ user_resize="false"
+ height="75"
+ width="313">
+
+ <layout_stack
+ follows="bottom|left|right"
+ layout="topleft"
+ name="button_row_ls"
+ left="1"
+ right="-1"
+ orientation="horizontal"
+ height="25"
+ top="1">
+ <layout_panel
+ follows="bottom|left|right"
+ layout="bottomleft"
+ name="layout_crt"
+ auto_resize="true"
+ height="23"
+ width="91">
+ <!-- placeholder to autoadjust buttons (since they are of different sizes)-->
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ layout="bottomleft"
+ name="layout_crt"
+ auto_resize="false"
+ height="23"
+ width="245">
+ <button
+ follows="bottom|left|right"
+ layout="topleft"
+ label="Create group for L$ [COST]"
+ name="btn_create"
+ visible="true"
+ tool_tip="Create a new Group"
+ height="23"
+ left="1"
+ top="0"
+ width="160" />
+ <button
+ follows="bottom|left|right"
+ name="back"
+ label="Cancel"
+ layout="topleft"
+ tool_tip="Return to list of groups"
+ left_pad="13"
+ height="23"
+ top="0"
+ width="70" />
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ layout="bottomleft"
+ name="layout_crt"
+ auto_resize="true"
+ height="23"
+ width="91">
+ <!-- placeholder to autoadjust buttons-->
+ </layout_panel>
+ </layout_stack>
+ <text
+ font="SansSerifSmall"
+ follows="top|left|right"
+ layout="topleft"
+ mouse_opaque="false"
+ type="string"
+ height="26"
+ left="6"
+ right="-6"
+ name="info_deletion"
+ top_pad="8"
+ word_wrap="true"
+ halign="center">
+ Note: After 7 days, a group with no members (other than the creator) is deleted
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 95312edfb9..05de249d22 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -280,17 +280,6 @@ background_visible="true"
left="1"
top="0"
width="90" />
- <button
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="1"
- top="0"
- label="Create Group"
- name="btn_create"
- visible="true"
- tool_tip="Create a new Group"
- width="90" />
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 47aceb2c2e..a5aca5c72b 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -59,7 +59,8 @@ Maximum 200 per group daily
<scroll_list.columns
label="Date"
name="date"
- width="60" />
+ sort_column="sort"
+ width="100" />
<scroll_list.columns
name="sort"
width="-1" />
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 13986c4030..e82305ef17 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -41,7 +41,7 @@
</string>
<string
name="acquired_date">
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</string>
<!-- Texture names for rating icons -->
<string
@@ -67,7 +67,7 @@
name="back_btn"
tool_tip="Back"
tab_stop="false"
- top="4"
+ top="2"
width="30"
use_draw_context_alpha="false" />
<text
@@ -78,24 +78,24 @@
left_pad="7"
name="title"
text_color="LtGray"
- top="3"
+ top="2"
use_ellipses="true"
value="Place Profile"
width="280" />
<scroll_container
color="DkGray2"
follows="all"
- height="532"
+ height="534"
layout="topleft"
left="9"
name="place_scroll"
opaque="true"
- top_pad="10"
- width="310">
+ top_pad="9"
+ width="324">
<panel
bg_alpha_color="DkGray2"
follows="left|top|right"
- height="630"
+ height="654"
layout="topleft"
left="0"
min_height="300"
@@ -112,35 +112,56 @@
name="logo"
top="10"
width="290" />
+ <!-- texture picker has an empty label section, compensate for it with negative top_pad-->
<text
follows="left|top|right"
font="SansSerifLarge"
height="14"
layout="topleft"
left="10"
- name="region_title"
+ top_pad="-10"
+ width="280"
+ name="parcel_title"
text_color="white"
- top_pad="10"
use_ellipses="true"
- value="SampleRegion"
- width="280" />
+ value="SampleParcel, Name Long" />
<text
follows="left|top|right"
height="14"
layout="topleft"
left="10"
- name="parcel_title"
- top_pad="10"
+ top_pad="9"
+ width="280"
+ name="region_title"
+ use_ellipses="true">
+ Region: [REGIONAMEPOS]
+ </text>
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="parcel_owner_label"
+ top_pad="7"
+ value="Owner:"
+ width="80" />
+ <text
+ follows="left|top|right"
+ height="15"
+ layout="topleft"
+ left_pad="0"
+ name="parcel_owner"
+ top_delta="0"
use_ellipses="true"
- value="SampleParcel, Name Long (145, 228, 26)"
- width="280" />
+ value="TempOwner"
+ width="215" />
<expandable_text
follows="left|top|right"
height="50"
layout="topleft"
left="10"
name="description"
- top_pad="10"
+ top_pad="7"
value="Du waltz die spritz"
width="280" />
<icon
@@ -163,19 +184,38 @@
width="268" />
<panel
follows="left|top|right"
- height="55"
+ height="81"
layout="topleft"
left="10"
name="landmark_info_panel"
top_pad="10"
width="290">
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="lod_tab_border"
+ top_pad="5"
+ width="290" />
+ <text
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="0"
+ name="this_landmark"
+ top_pad="8"
+ width="90">
+ This landmark:
+ </text>
<text
follows="left|top"
height="15"
layout="topleft"
left="0"
name="owner_label"
- top_pad="10"
+ top_pad="8"
value="Owner:"
width="90" />
<text
@@ -237,17 +277,30 @@
top_pad="10"
value="Title:"
width="290" />
- <text
- parse_urls="false"
- follows="left|top"
+ <line_editor
+ text_readonly_color="white"
+ enabled="false"
+ use_bg_color="true"
+ bg_color="DkGray0"
+ follows="left|top|right"
height="22"
layout="topleft"
left="0"
name="title_value"
text_color="white"
top_pad="5"
- use_ellipses="true"
- width="290" />
+ width="200" />
+ <button
+ follows="top|right"
+ height="24"
+ label="Edit"
+ layout="topleft"
+ left_pad="8"
+ mouse_opaque="false"
+ name="edit_btn"
+ tool_tip="Edit landmark information"
+ top_delta="-1"
+ width="83" />
<line_editor
follows="left|top|right"
height="22"
@@ -257,8 +310,8 @@
name="title_editor"
prevalidate_callback="ascii"
text_readonly_color="white"
- top_delta="0"
- width="290" />
+ top_delta="1"
+ width="290"/>
<text
follows="left|top"
height="15"
@@ -269,7 +322,7 @@
value="My notes:"
width="290" />
<text_editor
- bg_readonly_color="DkGray2"
+ bg_readonly_color="DkGray0"
follows="all"
height="75"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 67a09949ce..10b925ec93 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -1,198 +1,23 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
name="Landmarks"
- top="0"
- height="400"
layout="topleft"
left="0"
- width="313"
help_topic="panel_landmarks"
border="false"
background_visible="true"
bg_alpha_color="DkGray"
follows="all">
- <accordion
- background_visible="true"
- bg_alpha_color="DkGray2"
- bg_opaque_color="DkGray2"
- follows="all"
- height="373"
- layout="topleft"
- left="3"
- name="landmarks_accordion"
- top="0"
- width="307">
- <accordion_tab
- layout="topleft"
- name="tab_favorites"
- title="Favorites bar">
- <places_inventory_panel
- allow_multi_select="true"
- border="false"
- bottom="0"
- follows="all"
- height="126"
- left="0"
- mouse_opaque="true"
- name="favorites_list"
- scroll.hide_scrollbar="true"
- folder_view.use_ellipses="true"
- start_folder.name="Favorites"
- width="307"/>
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- name="tab_landmarks"
- title="My Landmarks">
- <places_inventory_panel
- allow_multi_select="true"
- border="false"
- bottom="0"
- follows="all"
- height="126"
- left="0"
- mouse_opaque="true"
- name="landmarks_list"
- scroll.hide_scrollbar="true"
- folder_view.use_ellipses="true"
- start_folder.name="Landmarks"
- width="307"/>
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- name="tab_inventory"
- title="My Inventory">
- <places_inventory_panel
- allow_multi_select="true"
- border="false"
- bottom="0"
- follows="all"
- height="126"
- left="0"
- mouse_opaque="true"
- name="my_inventory_list"
- scroll.hide_scrollbar="true"
- folder_view.use_ellipses="true"
- start_folder.name="My Inventory"
- width="307"/>
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- name="tab_library"
- title="Library">
- <places_inventory_panel
- allow_multi_select="true"
- border="false"
- bottom="0"
- follows="all"
- height="126"
- left="0"
- mouse_opaque="true"
- name="library_list"
- scroll.hide_scrollbar="true"
- folder_view.use_ellipses="true"
- start_folder.name="LIBRARY"
- width="313"/>
- </accordion_tab>
- </accordion>
- <panel
- background_visible="true"
- bevel_style="none"
- bottom="0"
- follows="left|right|bottom"
- height="27"
- layout="bottomleft"
- left="3"
- name="bottom_panel"
- width="313">
-
- <layout_stack
- animate="false"
- border_size="0"
- follows="left|right|bottom"
- height="25"
- layout="topleft"
- orientation="horizontal"
- top_pad="1"
- left="0"
- name="bottom_panel"
- width="307">
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="options_gear_btn_panel"
- width="32">
- <menu_button
- follows="bottom|left"
- tool_tip="Show additional options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="options_gear_btn"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="add_btn_panel"
- width="32">
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- name="add_btn"
- tool_tip="Add new landmark"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="true"
- height="25"
- layout="topleft"
- name="dummy_panel"
- width="212">
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- top="0"
- name="dummy_icon"
- width="211" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="trash_btn_panel"
- width="31">
- <dnd_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- left="0"
- layout="topleft"
- name="trash_btn"
- tool_tip="Remove selected landmark"
- top="0"
- width="31"/>
- </layout_panel>
- </layout_stack>
- </panel>
+ <places_inventory_panel
+ allow_multi_select="true"
+ border="false"
+ top="1"
+ follows="all"
+ left="3"
+ bottom="0"
+ right="-3"
+ mouse_opaque="true"
+ name="landmarks_list"
+ folder_view.use_ellipses="true"
+ start_folder.name="Landmarks"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 7759d4fdb2..ade004f9d0 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -33,7 +33,7 @@
auto_resize="false"
follows="left|right|top"
name="ui_container"
- width="1000"
+ width="1011"
left="0"
top="0"
height="172">
@@ -57,19 +57,15 @@
combo_editor.prevalidate_callback="ascii"
tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
name="username_combo"
- width="232">
+ width="206">
<combo_box.combo_editor
text_pad_left="8"
bg_image_always_focused="true"/>
- <combo_box.combo_button
- visible="false" />
- <combo_box.drop_down_button
- visible="false" />
</combo_box>
<line_editor
follows="left|top"
height="32"
- left_pad="-11"
+ left_pad="15"
max_length_chars="16"
text_pad_left="8"
name="password_edit"
@@ -119,36 +115,51 @@
width="120"
height="32"
left_pad="15"
- bottom_delta="0" />
+ bottom_delta="0" />
+ <text
+ follows="left|top"
+ font="SansSerifLarge"
+ font.style="BOLD"
+ text_color="EmphasisColor"
+ height="34"
+ name="sign_up_text"
+ left_pad="10"
+ width="200"
+ valign="center">
+ Sign up
+ </text>
<check_box
- control_name="RememberPassword"
follows="left|top"
font="SansSerifMedium"
left="185"
- bottom_delta="21"
+ bottom_delta="21"
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="SansSerifMedium"
text_color="EmphasisColor"
height="16"
- name="forgot_password_text"
- left="408"
+ left="408"
bottom_delta="0"
- width="200">
- Forgotten password
- </text>
+ label="Remember password"
+ word_wrap="down"
+ check_button.bottom="3"
+ name="remember_password"
+ width="165" />
<combo_box
allow_text_entry="false"
font="SansSerifTiny"
follows="left|top"
height="26"
left="588"
- bottom_delta="10"
+ bottom_delta="8"
max_chars="128"
label="Select grid"
layout="topleft"
@@ -159,12 +170,13 @@
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
- name="sign_up_text"
+ name="forgot_password_text"
left="778"
- bottom_delta="-10"
- width="200">
- Sign up
- </text>
+ bottom_delta="-8"
+ width="120"
+ halign="center">
+ Password help
+ </text>
</layout_panel>
<layout_panel
height="172"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index d77fbdec0a..2ff58035ed 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -32,30 +32,20 @@
left="12"
name="ItemcountText"
font="SansSerifMedium"
- text_color="EmphasisColor"
+ text_color="InventoryItemLinkColor"
use_ellipses="true"
top_pad="0"
width="300">
Items:
</text>
- <filter_editor
- text_pad_left="10"
- follows="left|top|right"
+ <combo_box
height="23"
- label="Enter search text"
layout="topleft"
left="10"
- max_length_chars="300"
- name="inventory search editor"
top="18"
- width="208" />
- <combo_box
- height="23"
- layout="topleft"
- left_pad="4"
name="search_type"
- follows="top|right"
- width="90">
+ follows="top|left"
+ width="88">
<item
label="Name"
name="Name"
@@ -72,7 +62,27 @@
label="UUID"
name="UUID"
value="search_by_UUID"/>
- </combo_box>
+ </combo_box>
+ <menu_button
+ follows="top|left"
+ tool_tip="Show search visibility options"
+ height="23"
+ image_overlay="Inv_Toolbar_SearchVisibility"
+ layout="topleft"
+ left_pad="3"
+ name="options_visibility_btn"
+ width="31" />
+ <filter_editor
+ text_pad_left="10"
+ follows="left|top|right"
+ height="23"
+ label="Enter search text"
+ layout="topleft"
+ left_pad="3"
+ max_length_chars="300"
+ highlight_text_field="true"
+ name="inventory search editor"
+ width="177" />
<tab_container
follows="all"
halign="center"
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 c7edba21f8..2dae2649a9 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -151,30 +151,43 @@
layout="topleft"
auto_resize="true"
user_resize="true"
- min_width="185"
+ min_width="254"
name="favorites_layout_panel"
- width="320">
+ width="342">
<icon
follows="top|left"
height="25"
image_name="ChatBarHandle"
layout="topleft"
- left="-323"
+ left="-345"
name="resize_handle"
top="4"
width="5" />
-
+ <button
+ height="23"
+ width="32"
+ layout="topleft"
+ mouse_opaque="true"
+ follows="left|top"
+ name="landmarks_btn"
+ tool_tip="My Landmarks"
+ top_delta="1"
+ left_pad="8"
+ scale_image="false"
+ image_overlay="Landmarks_overlay"
+ image_hover_unselected="PushButton_Over">
+ </button>
<favorites_bar
follows="left|right|top"
font="SansSerifSmall"
height="20"
layout="topleft"
- left="0"
+ left_pad="0"
top="4"
name="favorite"
image_drag_indication="Accordion_ArrowOpened_Off"
tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
- width="320">
+ width="310">
<label
follows="left|top"
height="13"
@@ -185,8 +198,8 @@
tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
top="13"
valign="bottom"
- width="102">
- Favorites Bar
+ width="205">
+ Your saved locations will appear here.
</label>
<!-- More button actually is a text box. -->
<more_button
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
deleted file mode 100644
index b2d8bb874b..0000000000
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel
- name="inventory_outbox"
- start_folder.name="Outbox"
- show_empty_message="false"
- start_folder.type="outbox"
- follows="all" layout="topleft"
- top="0" left="0" height="165" width="308"
- top_pad="0"
- bg_opaque_color="DkGray2"
- bg_alpha_color="DkGray2"
- background_visible="true"
- border="false"
- bevel_style="none"
- show_item_link_overlays="true"
- tool_tip="Drag and drop items here to prepare them for sale on your storefront"
- scroll.reserve_scroll_corner="false">
- <folder folder_arrow_image="Folder_Arrow"
- folder_indentation="8"
- item_height="20"
- item_top_pad="4"
- selection_image="Rounded_Square"
- left_pad="5"
- icon_pad="2"
- icon_width="16"
- text_pad="1"
- text_pad_right="4"
- arrow_size="12"
- max_folder_item_overlap="2"/>
- <item allow_wear="false"/>
-</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index 3f13cea58e..d625f89f3b 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -1,556 +1,561 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!-- Side tray Outfit Edit panel -->
<panel
- background_visible="true"
- border="false"
- height="600"
- follows="all"
- layout="topleft"
- help_topic="edit_outfit"
- left="0"
- min_height="350"
- name="outfit_edit"
- top="0"
- width="320">
- <string
- name="No Outfit"
- value="No Outfit"/>
- <string
- name="unsaved_changes"
- value="Unsaved Changes"/>
- <string
- name="now_editing"
- value="Now Editing"/>
- <string
- name="folder_view_off"
- value="Hierarchy_View_Disabled"
- translate="false"/>
- <string
- name="folder_view_on"
- value="Hierarchy_View_On"
- translate="false"/>
- <string
- name="list_view_off"
- value="List_View_Disabled"
- translate="false"/>
- <string
- name="list_view_on"
- value="List_View_On"
- translate="false"/>
+ background_visible="true"
+ border="false"
+ height="600"
+ follows="all"
+ layout="topleft"
+ help_topic="edit_outfit"
+ left="0"
+ min_height="350"
+ name="outfit_edit"
+ top="0"
+ width="320">
+ <string
+ name="No Outfit"
+ value="No Outfit"/>
+ <string
+ name="unsaved_changes"
+ value="Unsaved Changes"/>
+ <string
+ name="now_editing"
+ value="Now Editing"/>
+ <string
+ name="folder_view_off"
+ value="Hierarchy_View_Disabled"
+ translate="false"/>
+ <string
+ name="folder_view_on"
+ value="Hierarchy_View_On"
+ translate="false"/>
+ <string
+ name="list_view_off"
+ value="List_View_Disabled"
+ translate="false"/>
+ <string
+ name="list_view_on"
+ value="List_View_On"
+ translate="false"/>
- <panel.string
- name="not_available">
- (N\A)
- </panel.string>
- <panel.string
- name="unknown">
- (unknown)
- </panel.string>
+ <panel.string
+ name="not_available">
+ (N\A)
+ </panel.string>
+ <panel.string
+ name="unknown">
+ (unknown)
+ </panel.string>
- <!-- Wearables filtering strings -->
- <string name="Filter.All" value="All"/>
- <string name="Filter.Clothes/Body" value="Clothes/Body"/>
- <string name="Filter.Objects" value="Objects"/>
- <string name="Filter.Clothing" value="Clothing"/>
- <string name="Filter.Bodyparts" value="Body parts"/>
+ <!-- Wearables filtering strings -->
+ <string name="Filter.All" value="All"/>
+ <string name="Filter.Clothes/Body" value="Clothes/Body"/>
+ <string name="Filter.Objects" value="Objects"/>
+ <string name="Filter.Clothing" value="Clothing"/>
+ <string name="Filter.Bodyparts" value="Body parts"/>
- <string
- name="replace_body_part"
- value="Click to replace your existing shape"/>
+ <string
+ name="replace_body_part"
+ value="Click to replace your existing shape"/>
- <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="5"
- tab_stop="false"
- top="1"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="10"
- name="title"
- text_color="LtGray"
- top="0"
- value="Edit Outfit"
- use_ellipses="true"
- width="275" />
+ <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="5"
+ tab_stop="false"
+ top="1"
+ width="30"
+ use_draw_context_alpha="false" />
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="26"
+ layout="topleft"
+ left_pad="10"
+ name="title"
+ text_color="LtGray"
+ top="0"
+ value="Edit outfit parts"
+ use_ellipses="true"
+ width="275" />
- <!-- "HEADER WITH ICON, STATUS TEXT AND OUTFIT NAME" -->
- <panel
- background_visible="true"
- bg_alpha_color="DkGray2"
- bevel_style="none"
- follows="top|left|right"
- height="40"
- layout="topleft"
- left="6"
- name="header_panel"
- top_pad="5"
- width="311">
- <icon
- follows="left|top"
- height="31"
- image_name="Shirt_Large"
- left="2"
- mouse_opaque="false"
- name="outfit_icon"
- top="2"
- scale_image="true"
- visible="true"
- width="31" />
- <panel
- bevel_style="none"
- follows="top|left|right"
- height="37"
- layout="topleft"
- left_pad="5"
- name="outfit_name_and_status"
- top="2"
- width="270">
- <text
- follows="top|left|right"
- font="SansSerifSmallBold"
- height="13"
- layout="topleft"
- name="status"
- text_color="EmphasisColor"
- top="2"
- value="Now editing..."
- use_ellipses="true"
- width="245" />
- <text
- follows="bottom|left|right"
- font="SansSerifLargeBold"
- height="18"
- layout="topleft"
- name="curr_outfit_name"
- parse_urls="false"
- text_color="LtGray"
- top_pad="2"
- value="[Current Outfit]"
- use_ellipses="true"
- width="245" />
- <loading_indicator
- follows="right|top"
- height="24"
- layout="topleft"
- right="-2"
- name="edit_outfit_loading_indicator"
- top="6"
- width="24" />
- </panel>
- </panel>
+ <!-- "HEADER WITH ICON, STATUS TEXT AND OUTFIT NAME" -->
+ <panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ bevel_style="none"
+ follows="top|left|right"
+ height="40"
+ layout="topleft"
+ left="6"
+ name="header_panel"
+ top_pad="5"
+ width="311">
+ <icon
+ follows="left|top"
+ height="31"
+ image_name="Shirt_Large"
+ left="2"
+ mouse_opaque="false"
+ name="outfit_icon"
+ top="2"
+ scale_image="true"
+ visible="true"
+ width="31" />
+ <panel
+ bevel_style="none"
+ follows="top|left|right"
+ height="37"
+ layout="topleft"
+ left_pad="5"
+ name="outfit_name_and_status"
+ top="2"
+ width="270">
+ <text
+ follows="top|left|right"
+ font="SansSerifSmallBold"
+ height="13"
+ layout="topleft"
+ name="status"
+ text_color="EmphasisColor"
+ top="2"
+ value="Now editing..."
+ use_ellipses="true"
+ width="245" />
+ <text
+ follows="bottom|left|right"
+ font="SansSerifLargeBold"
+ height="18"
+ layout="topleft"
+ name="curr_outfit_name"
+ parse_urls="false"
+ text_color="LtGray"
+ top_pad="2"
+ value="[Current Outfit]"
+ use_ellipses="true"
+ width="245" />
+ <loading_indicator
+ follows="right|top"
+ height="24"
+ layout="topleft"
+ right="-2"
+ name="edit_outfit_loading_indicator"
+ top="6"
+ width="24" />
+ </panel>
+ </panel>
- <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) -->
- <!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height.
+ <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) -->
+ <!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height.
Required height for dragbar (icon in spec) is 10, so resizebar height should be 10 px.
It is calculated as border_size + 2*UIResizeBarOverlap
-->
- <layout_stack
- animate="true"
- border_size="8"
- clip="false"
- default_tab_group="2"
- follows="all"
- height="465"
- width="313"
- layout="topleft"
- orientation="vertical"
- name="im_panels"
- tab_group="1"
- top_pad="5"
- left="5">
- <layout_panel
- layout="topleft"
- height="187"
- min_height="155"
- name="outfit_wearables_panel"
- width="313"
- auto_resize="true"
- user_resize="true">
+ <layout_stack
+ animate="true"
+ border_size="8"
+ clip="false"
+ default_tab_group="2"
+ follows="all"
+ height="465"
+ width="313"
+ layout="topleft"
+ orientation="vertical"
+ name="im_panels"
+ tab_group="1"
+ top_pad="5"
+ left="5">
+ <layout_panel
+ layout="topleft"
+ height="187"
+ min_height="155"
+ name="outfit_wearables_panel"
+ width="313"
+ auto_resize="true"
+ user_resize="true">
- <layout_stack
- animate="true"
- border_size="0"
- follows="all"
- height="185"
- width="313"
- orientation="vertical"
- layout="topleft"
- name="filter_panels"
- top="0"
- left="0">
- <layout_panel
- auto_resize="true"
- background_visible="false"
- layout="topleft"
- height="154"
- name="add_button_and_combobox"
- width="311"
- visible="true">
+ <layout_stack
+ animate="true"
+ border_size="0"
+ follows="all"
+ height="185"
+ width="313"
+ orientation="vertical"
+ layout="topleft"
+ name="filter_panels"
+ top="0"
+ left="0">
+ <layout_panel
+ auto_resize="true"
+ background_visible="false"
+ layout="topleft"
+ height="154"
+ name="add_button_and_combobox"
+ width="311"
+ visible="true">
- <!-- List containing items from the COF and Base outfit -->
- <panel
- background_visible="false"
- class="cof_wearables"
- filename="panel_cof_wearables.xml"
- follows="all"
- height="129"
- layout="topleft"
- left="1"
- name="cof_wearables_list"
- top="0"
- width="311" />
+ <!-- List containing items from the COF and Base outfit -->
+ <panel
+ background_visible="false"
+ class="cof_wearables"
+ filename="panel_cof_wearables.xml"
+ follows="all"
+ height="129"
+ layout="topleft"
+ left="1"
+ name="cof_wearables_list"
+ top="0"
+ width="311" />
- <button
- follows="left|bottom"
- height="22"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Add More..."
- layout="topleft"
- left="2"
- name="show_add_wearables_btn"
- top_pad="2"
- tool_tip="Open/Close"
- width="125" />
+ <button
+ follows="left|bottom"
+ height="22"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Add More..."
+ layout="topleft"
+ left="2"
+ name="show_add_wearables_btn"
+ top_pad="2"
+ tool_tip="Open/Close"
+ width="125" />
- <combo_box
- follows="left|right|bottom"
- height="22"
- layout="topleft"
- left_pad="5"
- name="list_view_filter_combobox"
- top_delta="0"
- visible="false"
- width="152"/>
- <combo_box
- follows="left|right|bottom"
- height="22"
- layout="topleft"
- left_delta="0"
- name="folder_view_filter_combobox"
- top_delta="0"
- visible="false"
- width="152"/>
+ <combo_box
+ follows="left|right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="list_view_filter_combobox"
+ top_delta="0"
+ visible="false"
+ width="152"/>
+ <combo_box
+ follows="left|right|bottom"
+ height="22"
+ layout="topleft"
+ left_delta="0"
+ name="folder_view_filter_combobox"
+ top_delta="0"
+ visible="false"
+ width="152"/>
- <button
- follows="bottom|right"
- height="22"
- image_overlay="Search_Icon"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- layout="topleft"
- name="filter_button"
- right="-5"
- top_delta="0"
- visible="false"
- width="20" />
- </layout_panel>
+ <button
+ follows="bottom|right"
+ height="22"
+ image_overlay="Search_Icon"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ layout="topleft"
+ name="filter_button"
+ right="-5"
+ top_delta="0"
+ visible="false"
+ width="20" />
+ </layout_panel>
- <layout_panel
- auto_resize="false"
- background_visible="true"
- bg_alpha_color="DkGray2"
- height="30"
- name="filter_panel"
- width="311"
- visible="false">
+ <layout_panel
+ auto_resize="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ height="30"
+ name="filter_panel"
+ width="311"
+ visible="false">
- <filter_editor
- background_image="TextField_Search_Off"
- enabled="true"
- follows="left|right|top"
- label="Filter Inventory Wearables"
- layout="topleft"
- left="5"
- width="290"
- height="25"
- name="look_item_filter"
- search_button_visible="true"
- text_color="black"
- visible="true"/>
+ <filter_editor
+ background_image="TextField_Search_Off"
+ enabled="true"
+ follows="left|right|top"
+ label="Filter Inventory Wearables"
+ layout="topleft"
+ left="5"
+ width="290"
+ height="25"
+ name="look_item_filter"
+ search_button_visible="true"
+ text_color="black"
+ visible="true"/>
- </layout_panel>
- </layout_stack>
- </layout_panel>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
- <layout_panel background_visible="false"
- bg_alpha_color="DkGray2"
- auto_resize="true"
- height="450"
- min_height="80"
- name="add_wearables_panel"
- width="313"
- tab_group="2"
- user_resize="true"
- visible="false">
+ <layout_panel background_visible="false"
+ bg_alpha_color="DkGray2"
+ auto_resize="true"
+ height="450"
+ min_height="80"
+ name="add_wearables_panel"
+ width="313"
+ tab_group="2"
+ user_resize="true"
+ visible="false">
- <!-- this icon represent dragbar between layout panels.
+ <!-- this icon represent dragbar between layout panels.
This is a workaround implemented in EXT-7255 becouse of an issue with layout stack (EXT-7471) -->
- <icon follows="left|top|right"
- height="10"
- image_name="Dragbar"
- left="0"
- top_pad="-9"
- width="313" />
- <inventory_panel allow_multi_select="true"
- background_visible="false"
- border="false"
- follows="left|top|right|bottom"
- height="418"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="folder_view"
- top_pad="0"
- width="313"
- visible="false"/>
- <panel name="filtered_wearables_panel"
- background_opaque="true"
- background_visible="false"
- layout="topleft"
- follows="left|top|right|bottom"
- border="false"
- height="418"
- left="0"
- mouse_opaque="false"
- width="310"
- top_delta="0"
- visible="true">
- <wearable_items_list color="0.107 0.107 0.107 1"
- name="list_view"
- allow_select="true"
- layout="topleft"
- follows="all"
- multi_select="true"
- width="313"
- height="418"
- left="0"
- top="0"/>
- </panel>
- <button follows="bottom|left"
- height="22"
- left="2"
- label="Wear Item"
- layout="topleft"
- name="plus_btn"
- top_pad="5"
- width="130" />
- </layout_panel>
- </layout_stack>
+ <icon follows="left|top|right"
+ height="10"
+ image_name="Dragbar"
+ left="0"
+ top_pad="-9"
+ width="313" />
+ <inventory_panel allow_multi_select="true"
+ background_visible="false"
+ border="false"
+ follows="left|top|right|bottom"
+ height="418"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="folder_view"
+ top_pad="0"
+ width="313"
+ preinitialize_views="false"
+ visible="false"/>
+ <panel name="filtered_wearables_panel"
+ background_opaque="true"
+ background_visible="false"
+ layout="topleft"
+ follows="left|top|right|bottom"
+ border="false"
+ height="418"
+ left="0"
+ mouse_opaque="false"
+ width="310"
+ top_delta="0"
+ visible="true">
+ <wearable_items_list color="0.107 0.107 0.107 1"
+ name="list_view"
+ allow_select="true"
+ layout="topleft"
+ follows="all"
+ multi_select="true"
+ width="313"
+ height="418"
+ left="0"
+ top="0"/>
+ </panel>
+ <button follows="bottom|left"
+ height="22"
+ left="2"
+ label="Wear Item"
+ layout="topleft"
+ name="plus_btn"
+ top_pad="5"
+ width="130" />
+ </layout_panel>
+ </layout_stack>
- <!-- BUTTON BAR -->
- <panel
- background_visible="true"
- bevel_style="none"
- follows="bottom|left|right"
- height="27"
- layout="topleft"
- left="5"
- name="no_add_wearables_button_bar"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="gear_menu_btn"
- top="1"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_right_icon"
- width="250" />
- <button
- follows="bottom|right"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="Shop"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="shop_btn_1"
- top="1"
- tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"
- width="31" />
- </panel>
+ <!-- BUTTON BAR -->
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="bottom|left|right"
+ height="27"
+ layout="topleft"
+ left="5"
+ name="no_add_wearables_button_bar"
+ top_pad="0"
+ width="313">
+ <menu_button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Left_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Left_Selected"
+ image_unselected="Toolbar_Left_Off"
+ layout="topleft"
+ left="0"
+ name="gear_menu_btn"
+ top="1"
+ width="31" />
+ <icon
+ follows="bottom|left|right"
+ height="25"
+ image_name="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="1"
+ name="dummy_right_icon"
+ width="250" />
+ <button
+ follows="bottom|right"
+ height="25"
+ image_hover_unselected="Toolbar_Right_Over"
+ image_overlay="Shop"
+ image_selected="Toolbar_Right_Selected"
+ image_unselected="Toolbar_Right_Off"
+ layout="topleft"
+ left_pad="1"
+ name="shop_btn_1"
+ top="1"
+ tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"
+ width="31" />
+ </panel>
- <!-- BUTTON BAR - WEARABLES ADDING MODE -->
- <panel
- background_visible="true"
- bevel_style="none"
- follows="left|right|bottom"
- height="27"
- layout="topleft"
- left="5"
- name="add_wearables_button_bar"
- top_delta="0"
- visible="false"
- width="313">
- <menu_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="wearables_gear_menu_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="Hierarchy_View_Disabled"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- is_toggle="true"
- layout="topleft"
- left_pad="1"
- name="folder_view_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="List_View_On"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- is_toggle="true"
- layout="topleft"
- left_pad="1"
- name="list_view_btn"
- top="1"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_right_icon"
- width="186" >
- </icon>
- <button
- follows="bottom|right"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="Shop"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="shop_btn_2"
- top="1"
- tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"
- width="31" />
- </panel>
+ <!-- BUTTON BAR - WEARABLES ADDING MODE -->
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|right|bottom"
+ height="27"
+ layout="topleft"
+ left="5"
+ name="add_wearables_button_bar"
+ top_delta="0"
+ visible="false"
+ width="313">
+ <menu_button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Left_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Left_Selected"
+ image_unselected="Toolbar_Left_Off"
+ layout="topleft"
+ left="0"
+ name="wearables_gear_menu_btn"
+ top="1"
+ width="31" />
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Hierarchy_View_Disabled"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="1"
+ name="folder_view_btn"
+ top="1"
+ width="31" />
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="List_View_On"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="1"
+ name="list_view_btn"
+ top="1"
+ width="31" />
+ <icon
+ follows="bottom|left|right"
+ height="25"
+ image_name="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="1"
+ name="dummy_right_icon"
+ width="186" >
+ </icon>
+ <button
+ follows="bottom|right"
+ height="25"
+ image_hover_unselected="Toolbar_Right_Over"
+ image_overlay="Shop"
+ image_selected="Toolbar_Right_Selected"
+ image_unselected="Toolbar_Right_Off"
+ layout="topleft"
+ left_pad="1"
+ name="shop_btn_2"
+ top="1"
+ tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"
+ width="31" />
+ </panel>
- <!-- SAVE AND REVERT BUTTONS -->
- <panel
- follows="left|right|bottom"
- height="30"
- layout="topleft"
- left="4"
- top_pad="2"
- name="save_revert_button_bar"
- width="300">
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- mouse_opaque="false"
- name="button_bar_ls"
- left="0"
- orientation="horizontal"
- top="0"
- width="313">
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- mouse_opaque="false"
- name="save_btn_lp"
- auto_resize="true"
- width="156">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save"
- left="1"
- layout="topleft"
- name="save_btn"
- top="0"
- width="155" />
- <button
- follows="bottom|right"
- height="23"
- name="save_flyout_btn"
- label=""
- layout="topleft"
- left_pad="-20"
- tab_stop="false"
- top="0"
- image_selected="SegmentedBtn_Right_Selected_Press"
- image_unselected="SegmentedBtn_Right_Off"
- image_pressed="SegmentedBtn_Right_Press"
- image_pressed_selected="SegmentedBtn_Right_Selected_Press"
- image_overlay="Arrow_Small_Up"
- width="20"/>
- </layout_panel>
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="revert_btn_lp"
- auto_resize="true"
- width="147">
- <button
- follows="bottom|left|right"
- height="23"
- left="0"
- label="Undo Changes"
- layout="topleft"
- name="revert_btn"
- top="0"
- tool_tip="Revert to last saved version"
- width="147" />
- </layout_panel>
- </layout_stack>
- </panel>
+ <!-- SAVE AND REVERT BUTTONS -->
+ <panel
+ follows="left|right|bottom"
+ height="30"
+ layout="topleft"
+ left="4"
+ top_pad="2"
+ name="save_revert_button_bar"
+ width="300">
+ <layout_stack
+ follows="bottom|left|right"
+ height="23"
+ layout="topleft"
+ mouse_opaque="false"
+ name="button_bar_ls"
+ left="0"
+ orientation="horizontal"
+ top="0"
+ width="313">
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left="0"
+ mouse_opaque="false"
+ name="save_btn_lp"
+ auto_resize="true"
+ width="156">
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="Save changes"
+ left="1"
+ layout="topleft"
+ name="save_btn"
+ top="0"
+ width="155" />
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left_pad="3"
+ mouse_opaque="false"
+ name="save_as_btn_lp"
+ auto_resize="true"
+ width="156">
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="Save as..."
+ layout="topleft"
+ name="save_as_btn"
+ top="0"
+ left="1"
+ width="155" />
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left_pad="3"
+ mouse_opaque="false"
+ name="revert_btn_lp"
+ auto_resize="true"
+ width="147">
+ <button
+ follows="bottom|left|right"
+ height="23"
+ left="0"
+ label="Undo Changes"
+ layout="topleft"
+ name="revert_btn"
+ top="0"
+ tool_tip="Revert to last saved version"
+ width="147" />
+ </layout_panel>
+ </layout_stack>
+ </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
index 800faabc2a..441cf97e87 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
@@ -41,7 +41,7 @@
<text
follows="top|left"
font="SansSerif"
- height="56"
+ height="126"
layout="topleft"
left="10"
length="1"
@@ -50,7 +50,9 @@
width="200"
type="string"
word_wrap="true">
- Uploading an image to your inventory costs L$[UPLOAD_COST].
+Uploading an image to your inventory costs L$[UPLOAD_COST].
+
+Fee is based on your subscription level. Higher levels are charged lower fees.
</text>
<button
follows="right|bottom"
@@ -67,7 +69,7 @@
<button
follows="left|bottom"
height="23"
- label="UPLOAD L$10"
+ label="UPLOAD L$[UPLOAD_COST]"
layout="topleft"
left="10"
name="save_btn"
@@ -76,4 +78,4 @@
<button.commit_callback
function="Inventory.SaveOutfitPhoto" />
</button>
-</panel> \ No newline at end of file
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index eeb930485e..7b898dbd7f 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -30,7 +30,6 @@
tab_height="30"
tab_position="top"
halign="center"
- hide_scroll_arrows="true"
top="8"
width="315">
<panel
@@ -101,28 +100,33 @@
<button
follows="bottom|left|right"
height="23"
- label="Save As"
+ label="Save changes"
left="1"
layout="topleft"
name="save_btn"
top="0"
width="155" />
- <button
- follows="bottom|right"
- height="23"
- name="save_flyout_btn"
- label=""
- layout="topleft"
- left_pad="-20"
- tab_stop="false"
- image_selected="SegmentedBtn_Right_Selected_Press"
- image_unselected="SegmentedBtn_Right_Off"
- image_pressed="SegmentedBtn_Right_Press"
- image_pressed_selected="SegmentedBtn_Right_Selected_Press"
- image_overlay="Arrow_Small_Up"
- width="20"/>
- </layout_panel>
- <layout_panel
+ </layout_panel>
+ <layout_panel
+ follows="bottom|left|right"
+ height="23"
+ layout="bottomleft"
+ left_pad="3"
+ mouse_opaque="false"
+ name="save_as_btn_lp"
+ auto_resize="true"
+ width="156">
+ <button
+ follows="bottom|left|right"
+ height="23"
+ label="Save as..."
+ layout="topleft"
+ name="save_as_btn"
+ top="0"
+ left="1"
+ width="155" />
+ </layout_panel>
+ <layout_panel
follows="bottom|left|right"
height="23"
layout="bottomleft"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index a47121ae99..50035fd0e3 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -12,7 +12,7 @@
width="333">
<string
name="no_recent_people"
- value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
+ value="No recent people." />
<string
name="no_filtered_recent_people"
value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." />
@@ -30,8 +30,13 @@
value="No friends" />
<string
name="no_friends_msg">
- Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend.
-Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map].
+ To add someone as a friend, right-click on their avatar or their name.
+
+Looking for places with more people?
+
+[secondlife:///app/floater/destinations Destination Guide] has locations chosen by Second Life staff.
+
+[secondlife:///app/search/ Search] lets you search all of Second Life for certain keywords.
</string>
<string
name="no_filtered_friends_msg">
@@ -45,8 +50,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
name="no_filtered_groups_msg"
value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." />
<string
- name="no_groups_msg"
- value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." />
+ name="no_groups_msg">
+You are not a member of any groups.
+
+Learn about [https://community.secondlife.com/knowledgebase/joining-and-participating-in-groups-r51/ groups in Second Life.]
+ </string>
<string
name="MiniMapToolTipMsg"
value="[REGION](Double-click to open Map, shift-drag to pan)"/>
@@ -55,7 +63,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
value="[REGION](Double-click to teleport, shift-drag to pan)"/>
<string
name="GroupCountWithInfo"
- value="You belong to [COUNT] groups, and can join [REMAINING] more. [secondlife:/// Want more?]"/>
+ value="You belong to [COUNT] groups, and can join [REMAINING] more. [secondlife:/// Raise your limit]"/>
<tab_container
bottom="-10"
follows="all"
@@ -493,6 +501,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
top_pad="4"
left="3"
use_ellipses="true"
+ skip_link_underline="true"
name="groupcount">
You belong to [COUNT] groups, and can join [REMAINING] more.
</text>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 79d190e1e0..99c47eb825 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -103,7 +103,6 @@
height="100"
width="280"
parse_urls="true"
- hide_scrollbar="false"
layout="topleft"
left="10"
top_pad="2"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 43d580844f..4c0cdd321e 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -32,7 +32,6 @@
width="308" />
<texture_picker
allow_no_texture="true"
- border_enabled="true"
fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 0dd75b1b55..bdde2cab20 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -172,7 +172,7 @@
name="back_btn"
tool_tip="Back"
tab_stop="false"
- top="4"
+ top="2"
width="30"
use_draw_context_alpha="false" />
<text
@@ -183,24 +183,24 @@
left_pad="10"
name="title"
text_color="LtGray"
- top="4"
+ top="2"
use_ellipses="true"
value="Place Profile"
width="280" />
<scroll_container
color="DkGray2"
follows="all"
- height="572"
+ height="575"
layout="topleft"
left="9"
name="place_scroll"
opaque="true"
- top_pad="10"
- width="310">
+ top_pad="9"
+ width="324">
<panel
bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="580"
+ height="597"
layout="topleft"
left="0"
min_height="300"
@@ -277,32 +277,25 @@
height="14"
layout="topleft"
left="10"
- name="region_title"
- text_color="white"
top_pad="5"
+ width="290"
+ name="parcel_title"
+ text_color="white"
use_ellipses="true"
- value="SampleRegion"
- width="290" />
+ value="SampleParcel" />
<text
parse_urls="false"
follows="left|top|right"
height="14"
layout="topleft"
left="10"
- name="parcel_title"
- top_pad="4"
- use_ellipses="true"
- value="SampleParcel, Name Long (145, 228, 26)"
- width="285" />
- <expandable_text
- follows="left|top"
- height="50"
- layout="topleft"
- left="5"
- name="description"
- top_pad="10"
- value="Du waltz die spritz"
- width="285" />
+ top_pad="5"
+ width="285"
+ name="region_title"
+ text_color="White"
+ use_ellipses="true">
+ Region: [REGIONAMEPOS]
+ </text>
<text
follows="left|top"
height="14"
@@ -310,20 +303,28 @@
left="10"
name="owner_label"
text_color="White"
- top_pad="0"
+ top_pad="2"
value="Owner:"
- width="90" />
- <!--TODO: HOOK THIS NAME UP WITH AN INSPECTOR -->
+ width="80" />
<text
follows="left|top|right"
height="14"
layout="topleft"
- left_pad="1"
- name="owner_value"
+ left_pad="0"
+ name="parcel_owner"
top_delta="0"
value="Alex Superduperlongenamenton"
use_ellipses="true"
width="200" />
+ <expandable_text
+ follows="left|top"
+ height="50"
+ layout="topleft"
+ left="5"
+ name="description"
+ top_pad="10"
+ value="Du waltz die spritz"
+ width="285" />
<icon
follows="top|left"
height="16"
@@ -331,7 +332,7 @@
layout="topleft"
left="10"
name="maturity_icon"
- top_delta="0"
+ top_pad="0"
width="18" />
<text
follows="left|top|right"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 7d171490e8..58be4d4c5e 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -11,30 +11,156 @@ background_visible="true"
top="0"
left="0"
width="333">
- <string
- name="landmarks_tab_title"
- value="MY LANDMARKS" />
- <string
- name="teleport_history_tab_title"
- value="TELEPORT HISTORY" />
- <filter_editor
- text_pad_left="10"
- follows="left|top|right"
- font="SansSerifSmall"
- height="23"
- layout="topleft"
- left="10"
- label="Filter My Places"
- max_length_chars="300"
- name="Filter"
- tab_group="1"
- top="3"
- width="303" />
+ <string
+ name="landmarks_tab_title"
+ value="LANDMARKS" />
+ <string
+ name="teleport_history_tab_title"
+ value="VISITED" />
+ <string
+ name="favorites_tab_title"
+ value="FAVORITES" />
+ <string
+ name="tooltip_trash_items"
+ value="Remove selected landmark or folder" />
+ <string
+ name="tooltip_trash_history"
+ value="Delete list of visited places" />
+ <layout_stack
+ animate="false"
+ border_size="0"
+ follows="all"
+ height="564"
+ layout="topleft"
+ orientation="vertical"
+ top="1"
+ left="0"
+ name="places_layout_panel"
+ width="333">
+ <layout_panel
+ auto_resize="true"
+ height="538"
+ layout="topleft"
+ name="main_panel"
+ width="333">
+ <layout_stack
+ animate="false"
+ border_size="0"
+ follows="left|top|right"
+ height="27"
+ layout="topleft"
+ orientation="horizontal"
+ top="0"
+ left="0"
+ name="top_menu_panel"
+ width="320">
+ <layout_panel
+ auto_resize="true"
+ layout="topleft"
+ name="filter_panel"
+ width="193">
+ <filter_editor
+ text_pad_left="10"
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="23"
+ layout="topleft"
+ left="10"
+ label="Filter My Places"
+ max_length_chars="300"
+ name="Filter"
+ tab_group="1"
+ top="3"
+ width="181" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="options_gear_btn_panel"
+ width="32">
+ <menu_button
+ follows="bottom|left"
+ tool_tip="Show options"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ menu_position="bottomleft"
+ layout="topleft"
+ left="0"
+ name="options_gear_btn"
+ top="0"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="options_sort_btn_panel"
+ width="32">
+ <menu_button
+ follows="bottom|left"
+ tool_tip="Show sorting options"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ menu_position="bottomleft"
+ layout="topleft"
+ left="0"
+ name="sorting_menu_btn"
+ top="0"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="add_btn_panel"
+ width="32">
+ <menu_button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ menu_position="bottomleft"
+ layout="topleft"
+ left="0"
+ name="add_menu_btn"
+ tool_tip="Add new landmark or folder"
+ top="0"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="25"
+ layout="topleft"
+ name="trash_btn_panel"
+ width="31">
+ <dnd_button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Right_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Right_Selected"
+ image_unselected="Toolbar_Right_Off"
+ left="0"
+ layout="topleft"
+ name="trash_btn"
+ top="0"
+ width="31"/>
+ </layout_panel>
+ </layout_stack>
<tab_container
follows="all"
- halign="center"
- height="503"
layout="topleft"
+ halign="center"
+ height="504"
left="6"
name="Places Tabs"
tab_min_width="80"
@@ -42,46 +168,57 @@ background_visible="true"
tab_height="30"
tab_group="2"
tab_position="top"
- top_pad="10"
- width="315" />
+ top_pad="7"
+ width="318"
+ visible="true"/>
<panel
class="panel_place_profile"
filename="panel_place_profile.xml"
follows="all"
- height="533"
layout="topleft"
+ height="533"
left="0"
+ top="4"
help_topic="place_profile"
name="panel_place_profile"
- top="5"
visible="false"
- width="315" />
+ width="318" />
<panel
class="panel_landmark_info"
filename="panel_landmark_info.xml"
follows="all"
- height="533"
layout="topleft"
+ height="533"
left="0"
+ top="4"
help_topic="landmark"
name="panel_landmark_info"
- top="5"
visible="false"
- width="315" />
+ width="318" />
+ </layout_panel>
+
+ <!--*********************** Button wrappers ***********************-->
+ <layout_panel
+ auto_resize="false"
+ layout="topleft"
+ height="25"
+ name="button_layout_panel">
<panel
follows="bottom|left|right"
height="23"
layout="topleft"
left="4"
+ top="2"
name="button_panel"
- width="315">
-
+ width="318">
+
<layout_stack
follows="bottom|left|right"
height="23"
layout="topleft"
mouse_opaque="false"
name="bottom_bar_ls0"
+ animate="false"
left="4"
orientation="horizontal"
top="0"
@@ -150,8 +287,32 @@ background_visible="true"
width="85" />
</layout_panel>
</layout_stack>
- </layout_panel>
-
+ </layout_panel>
+ <!--*********************** Options button ***********************-->
+ <layout_panel
+ follows="bottom|right"
+ height="23"
+ layout="bottomleft"
+ left_pad="0"
+ mouse_opaque="false"
+ visible="false"
+ name="lp_options"
+ auto_resize="false"
+ width="23">
+ <menu_button
+ follows="bottom|right"
+ height="23"
+ image_disabled="ComboButton_UpOff"
+ image_unselected="ComboButton_UpOff"
+ image_selected="ComboButton_UpSelected"
+ layout="topleft"
+ mouse_opaque="false"
+ name="overflow_btn"
+ tool_tip="Show additional options"
+ top="0"
+ left="0"
+ width="23" />
+ </layout_panel>
<layout_panel
follows="bottom|left|right"
height="23"
@@ -159,103 +320,8 @@ background_visible="true"
left_pad="0"
mouse_opaque="false"
name="lp2"
- auto_resize="true"
+ auto_resize="true"
width="116">
-
- <!--*********************** Edit, Options buttons ***********************-->
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- mouse_opaque="false"
- name="bottom_bar_ls3"
- left="0"
- orientation="horizontal"
- top="0"
- width="113">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="0"
- mouse_opaque="false"
- name="edit_btn_lp"
- auto_resize="true"
- width="84">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- left="1"
- mouse_opaque="false"
- name="edit_btn"
- tool_tip="Edit landmark information"
- top="0"
- width="83" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|right"
- height="23"
- layout="bottomleft"
- left_pad="0"
- mouse_opaque="false"
- name="overflow_btn_lp"
- auto_resize="true"
- width="24">
- <menu_button
- follows="bottom|right"
- height="23"
- image_disabled="ComboButton_UpOff"
- image_unselected="ComboButton_UpOff"
- image_selected="ComboButton_UpSelected"
- layout="topleft"
- mouse_opaque="false"
- name="overflow_btn"
- tool_tip="Show additional options"
- top="0"
- left="1"
- width="23" />
- </layout_panel>
- </layout_stack>
-
- <!--*********************** Profile button ***********************-->
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- mouse_opaque="false"
- name="bottom_bar_profile_ls"
- left="0"
- orientation="horizontal"
- top="0"
- width="110">
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="profile_btn_lp"
- auto_resize="true"
- width="102">
- <button
- follows="bottom|left|right"
- height="23"
- label="Profile"
- layout="topleft"
- mouse_opaque="false"
- name="profile_btn"
- left="1"
- tool_tip="Show place profile"
- top="0"
- width="101" />
- </layout_panel>
- </layout_stack>
<!--*********************** Close button ***********************-->
@@ -300,6 +366,7 @@ background_visible="true"
<layout_stack
follows="bottom|left|right"
+ animate="false"
height="23"
layout="topleft"
mouse_opaque="false"
@@ -354,4 +421,6 @@ background_visible="true"
</layout_panel>
</layout_stack>
</panel>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 8296438d4c..d0518aa245 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -248,14 +248,27 @@
top_pad="5"
width="237"/>
<button
+ follows="top|left"
+ layout="topleft"
+ label="Remembered Usernames"
+ name="remembered_usernames"
height="20"
- label="Default Creation Permissions"
+ left="30"
+ top_pad="16"
+ width="200">
+ <button.commit_callback
+ function="Pref.RememberedUsernames" />
+ </button>
+ <button
+ follows="top|left"
layout="topleft"
+ label="Default Creation Permissions"
name="default_creation_permissions"
+ height="20"
left="30"
- top_pad = "20"
- width="250">
- <button.commit_callback
- function="Pref.PermsDefault" />
+ top_pad="16"
+ width="200">
+ <button.commit_callback
+ function="Pref.PermsDefault" />
</button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 9e7023d2f2..c023cb036e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -52,7 +52,7 @@
</check_box>
<check_box
- control_name="VoiceCallsFriendsOnly"
+ enabled="false"
height="16"
label="Only friends and groups can call or IM me"
layout="topleft"
@@ -99,6 +99,7 @@
label="Bubble Chat"
layout="topleft"
top_pad="4"
+ left_delta="0"
name="bubble_text_chat"
width="330">
</check_box>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
new file mode 100644
index 0000000000..9dab7d34e6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel
+ border="true"
+ follows="all"
+ height="408"
+ label="Controls"
+ layout="topleft"
+ left="102"
+ name="controls"
+ top="1"
+ width="517">
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ top="6"
+ left="10"
+ height="23"
+ width="232"
+ name="key_mode">
+ <combo_box.item
+ label="When in third person"
+ name="third_person"
+ value="1"/>
+ <combo_box.item
+ label="When in first person mode (Mouselook)"
+ name="first_person"
+ value="0"/>
+ <combo_box.item
+ label="When editing avatar"
+ name="edit_avatar"
+ value="2"/>
+ <combo_box.item
+ label="When sitting"
+ name="sitting"
+ value="3"/>
+ </combo_box>
+
+ <button
+ follows="top|left"
+ layout="topleft"
+ top="6"
+ right="-10"
+ height="23"
+ width="140"
+ label="Restore Defaults"
+ tool_tip="Restores default values for all control modes."
+ name="restore_defaults"/>
+
+ <scroll_list
+ draw_heading="true"
+ follows="all"
+ layout="topleft"
+ column_padding="0"
+ selection_type="header"
+ top="31"
+ left="3"
+ bottom="-3"
+ right="-3"
+ can_sort="false"
+ multi_select="false"
+ name="controls_list"
+ fg_disable_color="ScrollUnselectedColor"/>
+</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 4692a226d9..5aff7a5127 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -242,7 +242,7 @@
top_delta="24"
width="280">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<check_box
@@ -256,7 +256,7 @@
top_delta="24"
width="256">
<check_box.commit_callback
- function="Pref.VertexShaderEnable" />
+ function="Pref.RenderOptionUpdate" />
</check_box>
<slider
@@ -293,6 +293,21 @@
width="65">
0
</text>
+<text
+type="string"
+length="1"
+follows="left|top"
+height="16"
+layout="topleft"
+left_delta="68"
+name="IndirectMaxComplexityLink"
+mouse_opaque="false"
+top_delta="0"
+width="120">
+[https://community.secondlife.com/t5/Featured-News/Why-are-all-these-people-made-of-colored-jelly/ba-p/3031255 What's this?]
+</text>
+
+
<check_box
control_name="AlwaysRenderFriends"
height="16"
@@ -345,7 +360,6 @@
function="Pref.PrefLoad"
parameter="graphic"/>
</button>
- min_val="0.125"
<button
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 649403184d..2ea20570b1 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -322,17 +322,40 @@
name="enable_voice_check"
width="110"/>
<!-- -->
- <check_box
- name="media_auto_play_btn"
- control_name="ParcelMediaAutoPlayEnable"
- enabled_control="AudioStreamingMedia"
- value="true"
- follows="left|bottom|right"
- height="15"
- tool_tip="Check this to let media auto-play if it wants"
- label="Allow Media to auto-play"
- top_pad="1"
- left="25"/>
+ <text
+ follows="left|top"
+ layout="topleft"
+ height="15"
+ left="0"
+ top_pad="3"
+ width="120"
+ halign="right"
+ name="media_autoplay_label">
+ Media auto-play
+ </text>
+ <combo_box
+ control_name="ParcelMediaAutoPlayEnable"
+ enabled_control="AudioStreamingMedia"
+ follows="left|top"
+ layout="topleft"
+ height="23"
+ left_pad="7"
+ top_delta="-4"
+ name="media_auto_play_combo"
+ width="100">
+ <item
+ label="No"
+ name="autoplay_disabled"
+ value="0"/>
+ <item
+ label="Yes"
+ name="autoplay_enabled"
+ value="1"/>
+ <item
+ label="Ask"
+ name="autoplay_ask"
+ value="2"/>
+ </combo_box>
<check_box
name="media_show_on_others_btn"
control_name="MediaShowOnOthers"
@@ -440,63 +463,24 @@
enabled_control="EnableVoiceChat"
control_name="PushToTalkToggle"
height="15"
- label="Toggle speak on/off when I press:"
+ label="Toggle speak on/off when I press button in toolbar"
layout="topleft"
left="44"
name="push_to_talk_toggle_check"
width="237"
tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
top_pad="3"/>
- <line_editor
- follows="top|left"
- control_name="PushToTalkButton"
- enabled="false"
- enabled_control="EnableVoiceChat"
- height="23"
- left="80"
- max_length_bytes="200"
- name="modifier_combo"
- label="Push-to-Speak trigger"
- top_pad="3"
- width="200" />
- <button
- layout="topleft"
- follows="top|left"
- enabled_control="EnableVoiceChat"
- height="23"
- label="Set Key"
- left_pad="5"
- name="set_voice_hotkey_button"
- width="100">
- <button.commit_callback
- function="Pref.VoiceSetKey" />
- </button>
- <button
- enabled_control="EnableVoiceChat"
- follows="top|left"
- halign="center"
- height="23"
- image_overlay="Refresh_Off"
- layout="topleft"
- tool_tip="Reset to Middle Mouse Button"
- mouse_opaque="true"
- name="set_voice_middlemouse_button"
- left_pad="5"
- width="25">
- <button.commit_callback
- function="Pref.VoiceSetMiddleMouse" />
- </button>
<button
control_name="ShowDeviceSettings"
follows="left|top"
height="23"
is_toggle="true"
- label="Input/Output devices"
+ label="Voice Input/Output devices"
layout="topleft"
left="20"
top_pad="6"
name="device_settings_btn"
- width="190">
+ width="230">
</button>
<panel
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_presets_camera_pulldown.xml b/indra/newview/skins/default/xui/en/panel_presets_camera_pulldown.xml
new file mode 100644
index 0000000000..25d9c47449
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_presets_camera_pulldown.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_opaque="true"
+ background_visible="true"
+ bg_opaque_image="Volume_Background"
+ bg_alpha_image="Volume_Background"
+ border_visible="false"
+ border="false"
+ chrome="true"
+ follows="bottom"
+ height="155"
+ layout="topleft"
+ name="presets_camera_pulldown"
+ width="225">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ top="4"
+ left_delta="5"
+ font.style="BOLD"
+ name="Camera Presets"
+ width="120">
+ Camera Presets
+ </text>
+ <scroll_list
+ follows="left|top"
+ layout="topleft"
+ column_padding="0"
+ height="100"
+ width="215"
+ draw_heading="false"
+ draw_stripes="false"
+ bg_stripe_color="0.25 0.25 0.25 0.25"
+ top_delta="15"
+ left_delta="0"
+ name="preset_camera_list">
+ <scroll_list.columns
+ name="icon"
+ width="16" />
+ <scroll_list.columns
+ relative_width="1"
+ name="preset_name" />
+ <scroll_list.commit_callback
+ function="PresetsCamera.RowClick" />
+ </scroll_list>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="5"
+ name="horiz_separator"
+ top_delta="105"
+ width="215" />
+ <button
+ name="open_prefs_btn"
+ label="Open Camera floater"
+ tool_tip = "Bring up Camera floater"
+ top_delta="5"
+ left="15"
+ height="20"
+ width="200">
+ <button.commit_callback
+ function="Presets.toggleCameraFloater" />
+ </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 860caf2d21..e77d097d5f 100644
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -44,68 +44,129 @@
width="670" />
<layout_panel
auto_resize="false"
- height="250"
+ height="275"
layout="topleft"
- min_height="250"
+ min_height="275"
name="panel4"
width="670">
<icon
color="LoginProgressBoxCenterColor"
follows="left|right|bottom|top"
- height="250"
+ height="275"
image_name="Rounded_Square"
layout="topleft"
left="0"
top="0"
width="670" />
- <text
- follows="left|right|top"
- font="SansSerifHuge"
- font_shadow="none"
- halign="left"
- height="20"
- layout="topleft"
- left_delta="47"
- name="title_text"
- text_color="LoginProgressBoxTextColor"
- top_delta="50"
- right="-47"/>
- <text
- follows="left|right|top"
- font="SansSerif"
- font_shadow="none"
- halign="left"
- height="20"
- layout="topleft"
- left_delta="0"
- name="progress_text"
- text_color="LoginProgressBoxTextColor"
- top_pad="5"
- right="-47"
- word_wrap="true"/>
- <progress_bar
- bottom="115"
- color_bar="1 1 1 0.96"
- follows="left|right|top"
- height="16"
- layout="topleft"
- left="45"
- name="login_progress_bar"
- right="-45" />
- <text
+ <layout_stack
follows="left|right|top|bottom"
- font="SansSerifLarge"
- font_shadow="none"
- halign="left"
- height="100"
+ height="275"
layout="topleft"
- left="45"
- line_spacing.pixels="2"
- name="message_text"
- text_color="LoginProgressBoxTextColor"
- top="145"
- right="-90"
- word_wrap="true"/>
+ left="0"
+ orientation="vertical"
+ name="vertical_centering"
+ animate="false"
+ top="0"
+ width="670">
+ <layout_panel
+ auto_resize="false"
+ height="30"
+ layout="topleft"
+ min_height="30"
+ name="panel_top_spacer"
+ width="670">
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="100"
+ layout="topleft"
+ min_height="100"
+ name="panel_login"
+ width="670">
+ <text
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerifHuge"
+ font_shadow="none"
+ halign="left"
+ height="20"
+ left="47"
+ top="32"
+ right="-47"
+ name="title_text"
+ text_color="LoginProgressBoxTextColor"/>
+ <text
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerif"
+ font_shadow="none"
+ halign="left"
+ height="20"
+ top_pad="5"
+ right="-47"
+ left_delta="0"
+ name="progress_text"
+ text_color="LoginProgressBoxTextColor"
+ word_wrap="true"/>
+ <progress_bar
+ color_bar="0 0.67 0.9 0.96"
+ follows="left|right|top"
+ layout="topleft"
+ image_fill="ProgressBarSolid"
+ height="16"
+ left="45"
+ top_pad="5"
+ name="login_progress_bar"
+ right="-45" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="110"
+ layout="topleft"
+ min_height="110"
+ name="panel_motd"
+ width="670">
+ <text
+ follows="left|right|top|bottom"
+ font="SansSerifLarge"
+ font_shadow="none"
+ halign="left"
+ valign="center"
+ height="100"
+ layout="topleft"
+ left="45"
+ line_spacing.pixels="2"
+ name="message_text"
+ text_color="LoginProgressBoxTextColor"
+ top="7"
+ right="-90"
+ word_wrap="true"/>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ height="40"
+ layout="topleft"
+ min_height="40"
+ name="panel_icons"
+ width="670">
+ <!--Logos are tied to following label from code-->
+ <text
+ follows="left|right|top"
+ layout="topleft"
+ font="SansSerifLarge"
+ font_shadow="none"
+ halign="left"
+ height="16"
+ width="240"
+ left="47"
+ top="6"
+ line_spacing.pixels="2"
+ name="logos_lbl"
+ text_color="LoginProgressBoxTextColor">
+ Second Life uses
+ </text>
+ </layout_panel>
+ </layout_stack>
</layout_panel>
<layout_panel
height="200"
diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml
index aa38c49fae..edf1e1efd4 100644
--- a/indra/newview/skins/default/xui/en/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml
@@ -1,149 +1,903 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- border="true"
- follows="top|left"
- height="300"
- label="Environment"
- layout="topleft"
- help_topic="panel_region_environment_tab"
- name="panel_env_info"
- width="530">
- <text
- name="water_settings_title"
- follows="top|left"
- height="30"
- layout="topleft"
- left="50"
- top_pad="20"
- width="430"
- wrap="true">
- Select the Water and Sky/Day Cycle Settings you would like all visitors to your region to see. More info
- </text>
- <view_border
- bevel_style="none"
- follows="top|left"
- height="237"
- layout="topleft"
- left="50"
- name="border"
- top="60"
- width="430"/>
- <radio_group
- follows="top|left"
- height="45"
- layout="topleft"
- left_delta="10"
- name="region_settings_radio_group"
- top_delta="20"
- width="200">
- <radio_item
- label="Use Second Life default"
- layout="topleft"
- name="use_sl_default_settings"/>
- <radio_item
- label="Use the following settings"
- layout="topleft"
- name="use_my_settings"
- top_pad="20"/>
- </radio_group>
- <panel
- follows="top|left"
- height="150"
- layout="topleft"
- left="50"
- name="user_environment_settings"
- top_pad="20"
- width="430">
- <text
- name="water_settings_title"
- follows="top|left"
- height="16"
- layout="topleft"
- left="50"
- top_pad="0"
- width="160">
- Water Setting
- </text>
- <combo_box
- follows="top|left"
- left_pad="2"
- name="water_settings_preset_combo"
- top_delta="-7"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
- <text
- name="sky_dayc_settings_title"
- follows="top|left"
- height="16"
- layout="topleft"
- left="50"
- top_pad="30"
- width="100">
- Sky / Day Cycle
- </text>
- <radio_group
- layout="topleft"
- left_delta="50"
- name="sky_dayc_settings_radio_group"
- top_pad="10"
- height="50"
- width="110">
- <radio_item
- layout="topleft"
- label="Fixed sky"
- name="my_sky_settings"/>
- <radio_item
- layout="topleft"
- label="Day cycle"
- name="my_dayc_settings"
- top_pad="25"/>
- </radio_group>
- <combo_box
- follows="top|left"
- left_pad="2"
- name="sky_settings_preset_combo"
- top_delta="-7"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
- <combo_box
- follows="top|left"
- name="dayc_settings_preset_combo"
- top_delta="36"
- width="200">
- <combo_box.item
- label="-Select a preset-"
- name="item0"/>
- </combo_box>
- </panel>
- <button
- follows="left|top"
- height="23"
- label="Apply"
- layout="topleft"
- right="-160"
- name="apply_btn"
- top_pad="10"
- width="100" />
- <button
- follows="left|top"
- height="23"
- label="Cancel"
- layout="topleft"
- left_pad="10"
- name="cancel_btn"
- width="100" />
- <loading_indicator
- height="23"
- left="50"
- name="progress_indicator"
- top_delta="0"
- visible="false"
- width="23" />
+ border="true"
+ follows="all"
+ height="375"
+ label="Environment"
+ layout="topleft"
+ help_topic="panel_region_environment_tab"
+ name="panel_env_info"
+ width="530">
+ <string name="str_label_use_default">Use Default Settings</string>
+ <string name="str_label_use_region">Use Region Settings</string>
+ <string name="str_altitude_desription">Sky [INDEX]([ALTITUDE]m)</string>
+ <string name="str_no_parcel">No parcel is selected. Environmental settings are disabled.</string>
+ <string name="str_cross_region">Environmental settings are not available across region boundries.</string>
+ <string name="str_legacy">Environmental settings are not available on this region.</string>
+ <string name="str_disallowed">The estate manager does not allow changing parcel environments in this region.</string>
+ <string name="str_too_small">The parcel must be at least 128 square meters to support an environment.</string>
+ <string name="str_empty">(empty)</string>
+ <string name="str_region_env">(region environment)</string>
+
+ <layout_stack
+ width="530"
+ height="400"
+ follows="all"
+ layout="topleft"
+ left="0"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ user_resize="false"
+ auto_resize="false"
+ height="20"
+ name="pnl_environment_region_msg"
+ top="0">
+ <text follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="region_text_lbl"
+ top="6"
+ width="100">
+ Region:
+ </text>
+ <text follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left_delta="50"
+ name="region_text"
+ top_delta="0"
+ width="400">
+ unknown
+ </text>
+ </layout_panel>
+ <layout_panel
+ user_resize="false"
+ name="pnl_environment_disabled"
+ visible="false">
+ <text follows="top|left|bottom|right"
+ halign="center"
+ valign="top"
+ top_pad="40"
+ name="txt_environment_disabled"
+ text_color="white">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel
+ user_resize="false"
+ min_height="0"
+ top="0"
+ name="pnl_environment_config"
+ visible="true">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ user_resize="false"
+ min_height="0"
+ top="0"
+ name="pnl_environment_config"
+ visible="true">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ min_height="140"
+ follows="all"
+ border="true"
+ bevel_style="in"
+ name="pnl_environment_current">
+ <text follows="top|left"
+ font="SansSerif"
+ halign="left"
+ text_color="white"
+ left="5"
+ top="2">Select Environment</text>
+ <button
+ follows="top|left"
+ top_pad="20"
+ left_delta="10"
+ layout="topleft"
+ height="23"
+ label="[USEDEFAULT]"
+ width="120"
+ name="btn_usedefault"/>
+ <button
+ follows="top|left"
+ top_pad="5"
+ left_delta="0"
+ layout="topleft"
+ height="23"
+ label="Use Inventory"
+ width="120"
+ name="btn_select_inventory"/>
+ <button
+ follows="top|left"
+ top_pad="5"
+ left_delta="0"
+ layout="topleft"
+ height="23"
+ label="Customize"
+ width="120"
+ name="btn_edit"/>
+ <check_box
+ height="20"
+ label="Parcel Owners May Override Environment"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ name="chk_allow_override"
+ width="200" />
+ </layout_panel>
+ <layout_panel
+ min_height="130"
+ follows="all"
+ border="true"
+ bevel_style="in"
+ name="pnl_environment_length">
+ <text
+ font="SansSerif"
+ follows="top|left|right"
+ halign="left"
+ text_color="white"
+ left="5"
+ top="2">Day Settings</text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="10"
+ top_pad="16"
+ width="200">
+ Day Length (hours)
+ </text>
+ <slider
+ can_edit_text="true"
+ decimal_digits="1"
+ follows="top|left|right"
+ layout="topleft"
+ increment="0.5"
+ height="20"
+ width="237"
+ left="10"
+ top_pad="0"
+ right="-10"
+ initial_value="4"
+ name="sld_day_length"
+ min_val="4"
+ max_val="168" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="200">
+ Day Offset (hours)
+ </text>
+ <slider
+ can_edit_text="true"
+ decimal_digits="1"
+ follows="top|left|right"
+ layout="topleft"
+ height="20"
+ width="237"
+ increment="0.5"
+ initial_value="-8"
+ left="10"
+ top_pad="0"
+ right="-10"
+ name="sld_day_offset"
+ min_val="-11.5"
+ max_val="12" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="200">
+ Apparent Time of Day:
+ </text>
+ <text
+ name="lbl_apparent_time"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="10"
+ top_pad="5"
+ width="200">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel
+ follows="bottom"
+ border="true"
+ bevel_style="in"
+ name="pnl_environment_buttons">
+<!-- used to be buttons, but now spacer.
+-->
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ user_resize="false"
+ min_height="0"
+ top="0"
+ name="pnl_environment_altitudes"
+ visible="true">
+ <!-- Three movable panels first so that they will be 'below' slider-->
+ <panel
+ follows="top|left"
+ height="26"
+ width="360"
+ layout="topleft"
+ visible="true"
+ left="1"
+ top="30"
+ name="pnl_alt1">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ height="24"
+ width="52"
+ left_delta="2"
+ top_pad="1"
+ halign="right"
+ name="txt_alt1">
+ Sky [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor
+ follows="left|top"
+ enabled="false"
+ top_delta="3"
+ left_pad="21"
+ height="20"
+ layout="topleft"
+ name="edt_invname_alt1"
+ use_bg_color="true"
+ bg_color="TextBgReadOnlyColor"
+ width="155">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_alt1"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as current sky."
+ width="155" />
+ </panel>
+ <panel
+ follows="top|left"
+ height="26"
+ width="360"
+ layout="topleft"
+ visible="true"
+ left="1"
+ top="60"
+ name="pnl_alt2">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ height="24"
+ width="52"
+ left_delta="2"
+ top_pad="1"
+ halign="right"
+ name="txt_alt2">
+ Sky [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor
+ follows="left|top"
+ enabled="false"
+ top_delta="3"
+ left_pad="21"
+ height="20"
+ layout="topleft"
+ name="edt_invname_alt2"
+ use_bg_color="true"
+ bg_color="TextBgReadOnlyColor"
+ width="155">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_alt2"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as current sky."
+ width="155" />
+ </panel>
+ <panel
+ follows="top|left"
+ height="26"
+ width="360"
+ layout="topleft"
+ visible="true"
+ left="1"
+ top="90"
+ name="pnl_alt3">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ height="25"
+ width="52"
+ left_delta="2"
+ top_pad="1"
+ halign="right"
+ name="txt_alt3">
+ Sky [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor
+ follows="left|top"
+ enabled="false"
+ top_delta="3"
+ left_pad="21"
+ height="20"
+ layout="topleft"
+ name="edt_invname_alt3"
+ use_bg_color="true"
+ bg_color="TextBgReadOnlyColor"
+ width="155">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_alt3"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as current sky."
+ width="155" />
+ </panel>
+ <text follows="top|left"
+ font="SansSerif"
+ halign="left"
+ text_color="white"
+ left="5"
+ top="2">Sky Altitudes</text>
+ <!-- Divider icons also should be under slider to not interfer with clicks-->
+ <icon
+ color="LtGray"
+ height="2"
+ width="17"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left="57"
+ top="89"
+ name="mark0"/>
+ <icon
+ color="LtGray"
+ height="2"
+ width="17"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_delta="0"
+ top_delta="69"
+ name="mark1"/>
+ <icon
+ color="LtGray"
+ height="2"
+ width="17"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_delta="0"
+ top_delta="69"
+ name="mark2"/>
+ <multi_slider
+ height="270"
+ follows="top|left"
+ orientation="vertical"
+ increment="25"
+ min_val="100"
+ max_val="4000"
+ thumb_image="Inv_SettingsSky"
+ thumb_width="17"
+ thumb_highlight_color="white"
+ decimal_digits="0"
+ draw_track="true"
+ overlap_threshold="100"
+ initial_value="0"
+ layout="topleft"
+ left="57"
+ max_sliders="3"
+ name="sld_altitudes"
+ show_text="false"
+ top="20"
+ use_triangle="false"
+ width="17">
+ <slider name="sld1"
+ value="1000"/>
+ <slider name="sld2"
+ value="2000"/>
+ <slider name="sld3"
+ value="3000"/>
+ </multi_slider>
+ <panel
+ follows="top|left"
+ height="21"
+ width="360"
+ layout="topleft"
+ visible="true"
+ left="1"
+ top_pad="10"
+ name="pnl_ground">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ height="12"
+ width="52"
+ left_delta="2"
+ top_pad="2"
+ halign="right"
+ name="txt_ground">
+ Ground
+ </text>
+ <icon
+ follows="top|left"
+ height="17"
+ width="17"
+ image_name="Inv_SettingsSky"
+ layout="topleft"
+ name="icon_ground"
+ mouse_opaque="false"
+ visible="true"
+ top_delta="-3"
+ left_pad="2"/>
+ <line_editor
+ follows="left|top"
+ enabled="false"
+ top_delta="-1"
+ left_pad="2"
+ height="20"
+ layout="topleft"
+ name="edt_invname_ground"
+ use_bg_color="true"
+ bg_color="TextBgReadOnlyColor"
+ width="155">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_ground"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as the ground level sky."
+ width="155" />
+ </panel>
+ <panel
+ follows="top|left"
+ height="21"
+ width="360"
+ layout="topleft"
+ visible="true"
+ left="1"
+ top_pad="10"
+ name="pnl_water">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ height="12"
+ width="52"
+ left_delta="2"
+ top_pad="2"
+ halign="right"
+ name="txt_water">
+ Water
+ </text>
+ <icon
+ follows="left|top"
+ height="17"
+ width="17"
+ image_name="Inv_SettingsWater"
+ layout="topleft"
+ name="icon_water"
+ mouse_opaque="false"
+ visible="true"
+ top_delta="-3"
+ left_pad="2"/>
+ <line_editor
+ follows="left|top"
+ enabled="false"
+ top_delta="-1"
+ left_pad="2"
+ height="20"
+ layout="topleft"
+ name="edt_invname_water"
+ use_bg_color="true"
+ bg_color="TextBgReadOnlyColor"
+ width="155">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_water"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as current water."
+ width="155" />
+ </panel>
+ <button
+ follows="top|right"
+ layout="topleft"
+ height="23"
+ width="100"
+ label="Reset"
+ right="-10"
+ top_pad="4"
+ tool_tip="Reset to default altitudes"
+ name="btn_rst_altitudes" />
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <!--
+ <layout_panel
+ user_resize="false"
+ height="155"
+ min_height="0"
+ name="pnl_environment_config"
+ visible="true">
+ <layout_stack
+ left="5"
+ top="0"
+ right="-5"
+ bottom="-1"
+ layout="topleft"
+ follows="all"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ background_visible="true"
+ border="true"
+ bevel_style="in"
+ user_resize="false"
+ width="260"
+ min_width="260"
+ name="pnl_environment_current">
+ <text follows="top|left"
+ font="SansSerif"
+ halign="left"
+ text_color="white"
+ top="2">Current Environment</text>
+ <radio_group
+ height="90"
+ layout="topleft"
+ top_pad="8"
+ left_delta="10"
+ name="rdg_environment_select">
+ <radio_item
+ label="[USEDEFAULT]"
+ layout="topleft"
+ name="rdo_use_xxx_setting"
+ height="20"/>
+ <radio_item
+ label="Settings From Inventory"
+ layout="topleft"
+ valign="top"
+ name="rdo_use_inv_setting"
+ height="20"/>
+ <radio_item
+ top_pad="25"
+ label="Custom Environment"
+ layout="topleft"
+ height="20"
+ name="rdo_use_custom_setting"/>
+ </radio_group>
+ <line_editor
+ follows="top|left"
+ enabled="false"
+ left_delta="20"
+ top_delta="50"
+ height="20"
+ layout="topleft"
+ name="edt_inventory_name"
+ width="200">
+ Unknown
+ </line_editor>
+ <settings_drop_target
+ height="20"
+ top_pad="-20"
+ follows="top|left"
+ layout="topleft"
+ name="sdt_drop_target"
+ tool_tip="Drag a setting from Inventory onto this target box to select it as current evironment."
+ width="200" />
+ <button
+ name="btn_select_inventory"
+ follows="top|left"
+ image_overlay="Command_Inventory_Icon"
+ layout="topleft"
+ height="20"
+ width="20"
+ left_delta="205"
+ top_delta="0"/>
+ <button
+ follows="top|left"
+ top_pad="25"
+ left_delta="-205"
+ layout="topleft"
+ height="23"
+ label="Edit Environment"
+ width="120"
+ name="btn_edit"/>
+
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ user_resize="false"
+ width="260"
+ min_width="260"
+ background_visible="true"
+ name="pnl_environment_length">
+ <text
+ font="SansSerif"
+ follows="top|left|right"
+ halign="left"
+ text_color="white"
+ top="2">Day Settings</text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="10"
+ top_pad="14"
+ width="200">
+ Day Length (hours)
+ </text>
+ <slider
+ can_edit_text="true"
+ decimal_digits="1"
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ initial_value="4"
+ layout="topleft"
+ left_delta="0"
+ top_pad="6"
+ name="sld_day_length"
+ min_val="4"
+ max_val="168"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="200">
+ Day Offset (hours)
+ </text>
+ <slider
+ can_edit_text="true"
+ decimal_digits="1"
+ follows="left|top"
+ height="20"
+ increment="0.5"
+ initial_value="-8"
+ layout="topleft"
+ left_delta="0"
+ top_pad="6"
+ name="sld_day_offset"
+ min_val="-12"
+ max_val="12"
+ width="180" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="0"
+ top_pad="10"
+ width="200">
+ Apparent Time of Day:
+ </text>
+ <text
+ name="lbl_apparent_time"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="10"
+ top_pad="5"
+ width="200">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ user_resize="false"
+ height="155"
+ min_height="0"
+ name="pnl_environment_altitudes"
+ visible="true">
+ <panel
+ left="5"
+ top="0"
+ bottom="-1"
+ width="260"
+ follows="left|top|bottom"
+ background_visible="true"
+ border="true"
+ bevel_style="in"
+ name="cnt_panel">
+ <text follows="top|left"
+ font="SansSerif"
+ halign="left"
+ text_color="white"
+ top="2">Sky Altitudes</text>
+ <multi_slider
+ decimal_digits="0"
+ follows="bottom"
+ height="123"
+ width="17"
+ orientation="vertical"
+ increment="10"
+ overlap_threshold="100"
+ min_val="100"
+ max_val="4000"
+ layout="topleft"
+ left="15"
+ top="20"
+ max_sliders="20"
+ name="sld_altitudes"
+ show_text="false"
+ thumb_image="Inv_SettingsSky"
+ thumb_width="17"
+ thumb_highlight_color="white">
+ <slider name="sld1"
+ value="200"/>
+ <slider name="sld2"
+ value="400"/>
+ <slider name="sld3"
+ value="600"/>
+ </multi_slider>
+ <icon
+ follows="left|top"
+ height="17"
+ width="17"
+ image_name="Inv_SettingsSky"
+ layout="topleft"
+ name="icon_ground"
+ mouse_opaque="false"
+ visible="true"
+ left_delta="0"
+ top_pad="-9"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_pad="3"
+ top_delta="2"
+ width="200"
+ name="ground">
+ Ground
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left"
+ height="12"
+ layout="topleft"
+ left="35"
+ top="30"
+ width="200"
+ name="alt1">
+ Sky [INDEX]([ALTITUDE]m)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="35"
+ top="40"
+ width="200"
+ name="alt2">
+ Sky [INDEX]([ALTITUDE]m)
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="35"
+ top="50"
+ width="200"
+ name="alt3">
+ Sky [INDEX]([ALTITUDE]m)
+ </text>
+ </panel>
+ </layout_panel>
+ <layout_panel
+ user_resize="false"
+ height="0"
+ min_height="0"
+ name="pnl_auto_adjust"
+ visible="true"/>
+ <layout_panel
+ user_resize="false"
+ height="59"
+ min_height="59"
+ name="pnl_environment_buttons">
+ <check_box
+ height="20"
+ label="Parcel Owners May Override Environment"
+ layout="topleft"
+ left="10"
+ top="0"
+ name="chk_allow_override"
+ width="200" />
+ <button
+ follows="top|left"
+ height="23"
+ label="Apply"
+ top_pad="5"
+ name="btn_apply"
+ width="100" />
+ <button
+ follows="top|left"
+ height="23"
+ label="Reset"
+ layout="topleft"
+ left_pad="10"
+ top_delta="0"
+ name="btn_cancel"
+ width="100" />
+
+ </layout_panel>
+-->
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index ed37e9e2cc..545c01935b 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -145,10 +145,6 @@
name="Help"
width="112">
<menu_item_call
- label="Help..."
- layout="topleft"
- name="Help..." />
- <menu_item_call
label="Keyword Help..."
layout="topleft"
name="Keyword Help..." />
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
new file mode 100644
index 0000000000..6f82a0efa1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ label="Atmosphere &amp; Lighting"
+ layout="topleft"
+ left="0"
+ name="panel_settings_sky_atmos"
+ top="0">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ orientation="vertical">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ visible="true"
+ height="75">
+
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ width="80">
+ Ambient Color:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="ambient_light"
+ top_pad="5"
+ width="60" />
+ <text
+ follows="left"
+ height="10"
+ layout="topleft"
+ left_delta="90"
+ top_delta="-15"
+ width="80">
+ Blue Horizon:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="blue_horizon"
+ top_pad="5"
+ width="60" />
+ <text
+ follows="left"
+ height="10"
+ layout="topleft"
+ left_delta="90"
+ top_delta="-15"
+ width="80">
+ Blue Density:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="blue_density"
+ top_pad="5"
+ width="60" />
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true">
+ <layout_stack name="atmosphere1"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ follows="left|top|right|bottom"
+ orientation="hoizontal">
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ min_width="225">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ width="80">
+ Haze Horizon:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="5"
+ name="haze_horizon"
+ top_delta="20"
+ width="207"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Haze Density:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="5"
+ name="haze_density"
+ top_delta="20"
+ width="207"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Moisture Level:
+ </text>
+ <slider
+ decimal_digits="3"
+ follows="left|top"
+ height="14"
+ increment="0.001"
+ initial_value="0"
+ left_delta="5"
+ top_delta="20"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="moisture_level"
+ width="207"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Droplet Radius:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="14"
+ increment="0.01"
+ initial_value="0"
+ left_delta="5"
+ top_delta="20"
+ layout="topleft"
+ min_val="5.0"
+ max_val="1000.0"
+ name="droplet_radius"
+ width="207"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Ice Level:
+ </text>
+ <slider
+ decimal_digits="3"
+ follows="left|top"
+ height="14"
+ increment="0.001"
+ initial_value="0"
+ left_delta="5"
+ top_delta="20"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="ice_level"
+ width="207"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Scene Gamma:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ max_val="20"
+ name="scene_gamma"
+ top_delta="20"
+ width="207"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ min_width="225">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ width="200">
+ Density Multiplier:
+ </text>
+ <slider
+ decimal_digits="4"
+ follows="left|top"
+ height="16"
+ increment="0.0001"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.0001"
+ max_val="2"
+ name="density_multip"
+ 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">
+ Distance Multiplier:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0.8"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.05"
+ max_val="1000"
+ name="distance_multip"
+ 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">
+ Maximum Altitude:
+ </text>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="10000"
+ name="max_alt"
+ top_delta="20"
+ width="219"
+ can_edit_text="true"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..ac3b45d24c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ label="Clouds"
+ layout="topleft"
+ left="0"
+ help_topic="land_general_tab"
+ name="panel_settings_sky_clouds"
+ top="0">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ orientation="hoizontal">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="75">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ width="80">
+ Cloud Color:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="cloud_color"
+ top_pad="5"
+ width="60" />
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_delta="47"
+ width="200">
+ Cloud Coverage:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="cloud_coverage"
+ top_delta="20"
+ width="214"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="200">
+ Cloud Scale:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.01"
+ max_val="3"
+ name="cloud_scale"
+ top_delta="20"
+ width="214"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="200">
+ Cloud Variance:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1.0"
+ name="cloud_variance"
+ top_delta="20"
+ width="214"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="200">
+ Cloud Scroll:
+ </text>
+ <xy_vector
+ follows="left|top"
+ name="cloud_scroll_xy"
+ width="127"
+ height="145"
+ visible="true"
+ left_delta="0"
+ top_delta="21"
+ min_val_x="-30"
+ max_val_x="30"
+ min_val_y="-30"
+ max_val_y="30"
+ logarithmic="1"/>
+
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="160"
+ top_delta="-20"
+ width="200">
+ Cloud Image:
+ </text>
+ <texture_picker
+ height="123"
+ layout="topleft"
+ left_delta="5"
+ name="cloud_map"
+ top_pad="10"
+ width="100"/>
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="75">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ width="200">
+ Cloud Density:
+ </text>
+ <slider
+ label="X"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="cloud_density_x"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ <slider
+ label="Y"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ min_val="0"
+ max_val="1"
+ name="cloud_density_y"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ <slider
+ label="D"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ min_val="0"
+ max_val="3"
+ name="cloud_density_d"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="35"
+ width="200">
+ Cloud Detail:
+ </text>
+ <slider
+ label="X"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="cloud_detail_x"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ <slider
+ label="Y"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ min_val="0"
+ max_val="1"
+ name="cloud_detail_y"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ <slider
+ label="D"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ min_val="0"
+ max_val="1"
+ name="cloud_detail_d"
+ top_delta="20"
+ width="200"
+ can_edit_text="true"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..b3a33961bc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_density.xml
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ label="Density"
+ layout="topleft"
+ left="0"
+ help_topic="sky_density"
+ name="panel_settings_sky_density"
+ top="0">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ orientation="vertical">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="12">
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="rayleigh_exponential"
+ label="Rayleigh Exponential Term:"
+ top_pad="12"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="-0.01"
+ max_val="0.01"
+ name="rayleigh_exponential_scale"
+ label="Rayleigh Exponential Scale:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="0.00001"
+ name="rayleigh_linear"
+ label="Rayleigh Linear Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="rayleigh_constant"
+ label="Rayleigh Constant Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ height="14"
+ initial_value="0"
+ layout="topleft"
+ min_val="1000"
+ max_val="40000"
+ name="rayleigh_max_altitude"
+ label="Rayleigh Max Altitude:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="14">
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="3.0"
+ name="mie_exponential"
+ label="Mie Exponential Term:"
+ top_pad="12"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="-0.01"
+ max_val="0.01"
+ name="mie_exponential_scale"
+ label="Mie Exponential Scale:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="0.000004"
+ name="mie_linear"
+ label="Mie Linear Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="mie_constant"
+ label="Mie Constant Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="14"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ min_val="0.2"
+ max_val="1.8"
+ name="mie_aniso_factor"
+ label="Mie Aniso Factor:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ height="14"
+ increment="0.1"
+ initial_value="0"
+ layout="topleft"
+ min_val="1000"
+ max_val="30000"
+ name="mie_max_altitude"
+ label="Mie Max Altitude:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="12">
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1"
+ name="absorption_exponential"
+ label="Absorption Exponential Term:"
+ top_pad="8"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="-1"
+ max_val="1"
+ name="absorption_exponential_scale"
+ label="Absorption Exponential Scale:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="absorption_linear"
+ label="Absorption Linear Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="6"
+ follows="left|top"
+ height="14"
+ increment="0.0000001"
+ initial_value="0"
+ layout="topleft"
+ min_val="0"
+ max_val="1"
+ name="absorption_constant"
+ label="Absorption Constant Term:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ height="14"
+ increment="0.1"
+ initial_value="0"
+ layout="topleft"
+ min_val="1000"
+ max_val="25000"
+ name="absorption_max_altitude"
+ label="Absorption Max Altitude:"
+ width="400"
+ label_width="160"
+ can_edit_text="true"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..1ad78dbb13
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ label="Sun &amp; Moon"
+ layout="topleft"
+ left="0"
+ name="panel_settings_sky_hbodies"
+ top="0">
+ <layout_stack
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ orientation="horizontal">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ name="sun_layout"
+ height="400">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ font="SansSerifBold"
+ width="120">
+ Sun &amp; Stars
+ </text>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="10"
+ top_delta="25"
+ width="100">
+ Position:
+ </text>
+ <sun_moon_trackball
+ name="sun_rotation"
+ follows="left|top"
+ left_delta="0"
+ top_delta="20"
+ height="150"
+ width="150"
+ thumb_mode="sun" />
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="160"
+ top_delta="-20"
+ width="200">
+ Image:
+ </text>
+ <texture_picker
+ height="123"
+ layout="topleft"
+ left_delta="5"
+ name="sun_image"
+ top_pad="10"
+ width="100"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="110"
+ width="80">
+ Scale:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.25"
+ max_val="20"
+ name="sun_scale"
+ top_delta="15"
+ width="130"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="65"
+ top_delta="20"
+ width="80">
+ Color:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="5"
+ name="sun_moon_color"
+ top_pad="5"
+ width="60" />
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-235"
+ top_delta="-3"
+ width="200">
+ Azimuth:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="359.99"
+ name="sun_azimuth"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Elevation:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-90"
+ max_val="90"
+ name="sun_elevation"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Glow Focus:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-2"
+ max_val="2"
+ name="glow_focus"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Glow Size:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="1.99"
+ name="glow_size"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Star Brightness:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="500"
+ name="star_brightness"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+
+ <check_box
+ control_name="sunbeacon"
+ follows="left|top"
+ layout="topleft"
+ width="60"
+ height="16"
+ label="Show Beacon"
+ name="sunbeacon"
+ top_pad="5"
+ left_delta="-8"/>
+
+ </layout_panel>
+ <layout_panel
+ border="false"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ height="400">
+ <layout_stack
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ follows="left|top|right|bottom"
+ orientation="vertical">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ name="moon_layout"
+ height="220">
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="15"
+ top_pad="15"
+ font="SansSerifBold"
+ width="80">
+ Moon
+ </text>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="10"
+ top_delta="25"
+ width="100">
+ Position:
+ </text>
+ <sun_moon_trackball
+ name="moon_rotation"
+ follows="left|top"
+ left_delta="0"
+ top_delta="20"
+ height="150"
+ width="150"
+ thumb_mode="moon" />
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="160"
+ top_delta="-20"
+ width="200">
+ Image:
+ </text>
+ <texture_picker
+ height="123"
+ layout="topleft"
+ left_delta="5"
+ name="moon_image"
+ top_pad="10"
+ width="100"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="110"
+ width="80">
+ Scale:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.25"
+ max_val="20"
+ name="moon_scale"
+ top_delta="15"
+ width="130"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-170"
+ top_delta="32"
+ width="200">
+ Azimuth:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="359.99"
+ name="moon_azimuth"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Elevation:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-90"
+ max_val="90"
+ name="moon_elevation"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="22"
+ width="200">
+ Brightness:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0.0"
+ max_val="1.0"
+ name="moon_brightness"
+ top_delta="13"
+ width="215"
+ can_edit_text="true"/>
+ <check_box
+ control_name="moonbeacon"
+ follows="left|top"
+ layout="topleft"
+ width="60"
+ height="16"
+ label="Show Beacon"
+ name="moonbeacon"
+ top_pad="5"
+ left_delta="-8"/>
+
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_settings_water.xml b/indra/newview/skins/default/xui/en/panel_settings_water.xml
new file mode 100644
index 0000000000..991ce25bec
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="all"
+ label="Water"
+ layout="topleft"
+ left="0"
+ help_topic="land_general_tab"
+ name="panel_settings_water"
+ top="0">
+ <layout_stack name="water_stack1"
+ follows="all"
+ layout="topleft"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ orientation="vertical">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="false"
+ user_resize="false"
+ visible="true"
+ height="105">
+ <text
+ follows="left|top"
+ height="20"
+ font="SansSerif"
+ layout="topleft"
+ left="5"
+ top="5"
+ width="215">
+ Water Fog:
+ </text>
+ <text
+ follows="left|top"
+ height="10"
+ layout="left|top"
+ left_delta="15"
+ top_delta="0"
+ width="60">
+ Color:
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="37"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ name="water_fog_color"
+ top_pad="5"
+ width="60" />
+ <text
+ follows="left|top"
+ height="10"
+ top_delta="-15"
+ left_delta="80"
+ width="150">
+ Density Exponent:
+ </text>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="top"
+ left_delta="15"
+ min_val="-10"
+ max_val="10"
+ name="water_fog_density"
+ top_delta="5"
+ width="150"
+ can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ top_delta="25"
+ left_delta="-15"
+ width="150">
+ Underwater Modifier:</text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="top"
+ left_delta="15"
+ min_val="0.0"
+ max_val="20.0"
+ name="water_underwater_mod"
+ top_delta="20"
+ width="150"
+ can_edit_text="true"/>
+
+ <text
+ follows="left|top|right"
+ height="10"
+ layout="topleft"
+ left_delta="165"
+ top_delta="-53"
+ width="150">
+ Fresnel Scale:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0.7"
+ layout="topleft"
+ left_delta="5"
+ name="water_fresnel_scale"
+ top_delta="15"
+ width="150"
+ can_edit_text="true"/>
+ <text
+ follows="left|top|right"
+ layout="topleft"
+ left_delta="-5"
+ name="FresnelOffsetText"
+ top_delta="25"
+ width="150">
+ Fresnel Offset:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ increment="0.01"
+ initial_value="0.7"
+ height="16"
+ layout="topleft"
+ left_delta="5"
+ name="water_fresnel_offset"
+ top_pad="5"
+ width="150"
+ can_edit_text="true"/>
+
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ user_resize="false"
+ visible="true">
+ <layout_stack name="water_stack2"
+ left="5"
+ top="5"
+ right="-5"
+ bottom="-5"
+ follows="left|top|right|bottom"
+ orientation="horizontal">
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ visible="true"
+ min_width="460"
+ width="50">
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="15"
+ top="5"
+ width="215">
+ Normal Map
+ </text>
+ <texture_picker
+ height="84"
+ layout="topleft"
+ left_delta="0"
+ name="water_normal_map"
+ top_pad="5"
+ width="61"/>
+
+ <text
+ follows="left|top"
+ height="16"
+ width="120"
+ layout="topleft"
+ top_delta="-20"
+ left_delta="175">
+ Large Wave Speed
+ </text>
+ <xy_vector
+ follows="top|left"
+ name="water_wave1_xy"
+ width="120"
+ height="145"
+ visible="true"
+ left_delta="0"
+ top_delta="21"
+ min_val_x="-20"
+ max_val_x="20"
+ increment_x="0.01f"
+ min_val_y="-20"
+ max_val_y="20"
+ increment_y="0.01f"
+ arrow_color="white"/>
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ top_delta="-20"
+ left_delta="140">
+ Small Wave Speed
+ </text>
+ <xy_vector
+ follows="top|left"
+ name="water_wave2_xy"
+ width="120"
+ height="145"
+ visible="true"
+ left_delta="0"
+ top_delta="21"
+ min_val_x="-20"
+ max_val_x="20"
+ min_val_y="-20"
+ max_val_y="20"
+ increment_x="0.01f"
+ increment_y="0.01f"
+ arrow_color="white"/>
+
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="90"
+ width="215">
+ Reflection Wavelet Scale
+ </text>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ increment="0.01"
+ height="16"
+ initial_value="0.7"
+ layout="topleft"
+ label="X:"
+ left_delta="10"
+ max_val="10"
+ name="water_normal_scale_x"
+ top_pad="5"
+ width="150"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ increment="0.01"
+ initial_value="0.7"
+ height="16"
+ layout="topleft"
+ max_val="10"
+ name="water_normal_scale_y"
+ top_pad="6"
+ label="Y:"
+ width="150"
+ can_edit_text="true"/>
+ <slider
+ decimal_digits="1"
+ follows="left|top"
+ increment="0.01"
+ initial_value="0.7"
+ height="16"
+ layout="topleft"
+ max_val="10"
+ name="water_normal_scale_z"
+ top_pad="6"
+ label="Z:"
+ width="150"
+ can_edit_text="true"/>
+
+ </layout_panel>
+ <layout_panel
+ border="true"
+ bevel_style="in"
+ auto_resize="true"
+ user_resize="false"
+ width="50"
+ visible="true">
+ <text
+ follows="left|top"
+ height="20"
+ font="SansSerif"
+ layout="topleft"
+ left="5"
+ top="5"
+ width="215">
+ Refraction And Blur:
+ </text>
+ <text
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ top_delta="25"
+ left_delta="5"
+ width="215">
+ Refraction Scale (Above)
+ </text>
+ <slider
+ control_name="water_scale_above"
+ decimal_digits="2"
+ follows="left|top"
+ increment="0.01"
+ initial_value="0.1"
+ height="16"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="3"
+ name="water_scale_above"
+ top_pad="5"
+ width="200"
+ can_edit_text="true" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="16"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="215">
+ Refraction Scale (Below)
+ </text>
+ <slider
+ control_name="water_scale_below"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="3"
+ name="water_scale_below"
+ top_pad="5"
+ width="200"
+ can_edit_text="true"/>
+ <text
+ follows="left|top|right"
+ font="SansSerif"
+ height="16"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="5"
+ width="215">
+ Blur Multiplier
+ </text>
+ <slider
+ control_name="water_blur_multip"
+ follows="left|top"
+ height="16"
+ increment="0.001"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="-0.5"
+ max_val="0.5"
+ name="water_blur_multip"
+ top_pad="5"
+ width="200"
+ can_edit_text="true"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
index d019a0a310..8cc27d9eef 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
@@ -118,7 +118,7 @@
width="200"
type="string"
word_wrap="true">
- Saving an image to your inventory costs L$[UPLOAD_COST]. To save your image as a texture select one of the square formats.
+ To save your image as a texture select one of the square formats.
</text>
<button
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 2fe4cf8183..8fc5cd7e63 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -73,4 +73,18 @@
<button.commit_callback
function="Snapshot.SaveToEmail" />
</button>
+ <text
+ follows="top|left"
+ font="SansSerif"
+ height="56"
+ layout="topleft"
+ left="10"
+ length="1"
+ name="fee_hint_lbl"
+ top_pad="7"
+ width="200"
+ type="string"
+ word_wrap="true">
+ Fee is based on your subscription level. Higher levels are charged lower fees.
+ </text>
</panel> \ No newline at end of file
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 52bcce01f7..ada980cda1 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -75,7 +75,7 @@
</panel>
<panel
height="18"
- left="-416"
+ left="-458"
width="185"
top="1"
follows="right|top"
@@ -148,11 +148,19 @@
<icon
follows="right|top"
height="16"
- image_name="Presets_Icon"
+ image_name="Cam_FreeCam_Off"
left_pad="8"
top="2"
- name="presets_icon"
+ name="presets_icon_camera"
width="18" />
+ <icon
+ follows="right|top"
+ height="13"
+ image_name="Presets_Icon"
+ left_pad="8"
+ top="4"
+ name="presets_icon_graphic"
+ width="16" />
<button
follows="right|top"
height="16"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index 768efc2f3f..55c47c90a4 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -6,7 +6,7 @@
bg_alpha_color="DkGray">
<accordion
follows="left|top|right|bottom"
- height="373"
+ height="400"
layout="topleft"
left="3"
top="0"
@@ -147,37 +147,4 @@
</flat_list_view>
</accordion_tab>
</accordion>
- <panel
- background_visible="true"
- bevel_style="none"
- bottom="0"
- follows="left|right|bottom"
- height="27"
- layout="bottomleft"
- left="3"
- name="bottom_panel"
- width="313">
- <menu_button
- follows="bottom|left"
- tool_tip="Show additional options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="gear_btn"
- top="1"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="273"
- />
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index f79d752fdb..bda08f3421 100644
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -92,7 +92,10 @@
<action description="Toggle various About Land &gt; Options settings"
longdescription="Toggle &apos;Safe (no damage)&apos;, &apos;Fly&apos;, and allow other Residents to: &apos;Edit Terrain&apos;, &apos;Build&apos;, &apos;Create Landmarks&apos;, and &apos;Run Scripts&apos; on group-owned land in About Land &gt; Options tab."
name="land options" value="22" />
- </action_set>
+ <action description="Modify environment settings and day cycle."
+ longdescription="Change the environment settings and day cycle from the About Land &gt; Environment tab."
+ name="land change environment" value="46" />
+ </action_set>
<action_set
description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels."
name="Parcel Powers">
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 2a1eb425ed..1777a0db05 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -32,7 +32,7 @@ width="333">
top="5"
follows="left|top|right"
layout="topleft"
- width="303"
+ width="307"
height="33"
name="panel_currentlook"
>
@@ -118,14 +118,14 @@ width="333">
name="Filter"
search_button_visible="true"
top_pad="10"
- width="303" />
+ width="307" />
<panel
class="panel_outfits_inventory"
filename="panel_outfits_inventory.xml"
name="panel_outfits_inventory"
height="493"
min_height="410"
- width="320"
+ width="325"
visible="false"
left="0"
tab_group="1"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index acb6f5b42a..9a68479d05 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -33,7 +33,7 @@
</panel.string>
<panel.string
name="acquiredDate">
- [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</panel.string>
<panel.string
name="origin_inventory">
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 454616340a..f604a16b0b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -28,7 +28,7 @@
<string name="BuildConfig">Build Configuration [BUILD_CONFIG]</string>
<string name="AboutPosition">
-You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt;
SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
@@ -107,7 +107,9 @@ Voice Server Version: [VOICE_VERSION]
<string name="CertExpired">The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.</string>
<string name="CertKeyUsage">The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.</string>
<string name="CertBasicConstraints">Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.</string>
+ <string name="CertInvalid">Could not load certificate. Please contact your Grid administrator.</string>
<string name="CertInvalidSignature">The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.</string>
+ <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>
@@ -300,6 +302,17 @@ Please try logging in again in a minute.</string>
<string name="BUTTON_DOCK">Dock</string>
<string name="BUTTON_HELP">Show Help</string>
+ <!-- ToolTips for notecards -->
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+Items of this type can't be attached
+to notecards on this region.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+Only items with unrestricted
+'next owner' permissions
+can be attached to notecards.
+ </string>
+
<!-- searching - generic -->
<string name="Searching">Searching...</string>
<string name="NoneFound">None found.</string>
@@ -352,6 +365,11 @@ Error in upload request. Please visit
http://secondlife.com/support for help fixing this problem.
</string>
+ <!-- Settings errors -->
+ <string name="SettingValidationError">Validation failed for importing settings [NAME]</string>
+ <string name="SettingImportFileError">Could not open file [FILE]</string>
+ <string name="SettingParseFileError">Could not open file [FILE]</string>
+ <string name="SettingTranslateError">Could not translate legacy windlight [NAME]</string>
<!-- Asset Type human readable names: these will replace variable [TYPE] in notification FailedToFindWearable* -->
<!-- Will also replace [OBJECTTYPE] in notifications: UserGiveItem, ObjectGiveItem -->
<string name="texture">texture</string>
@@ -379,7 +397,8 @@ http://secondlife.com/support for help fixing this problem.
<string name="favorite">favorite</string>
<string name="symbolic link">link</string>
<string name="symbolic folder link">folder link</string>
- <string name="mesh">mesh</string>
+ <string name="settings blob">settings</string>
+ <string name="mesh">mesh</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
<string name="AvatarEditingAppearance">(Editing Appearance)</string>
@@ -504,6 +523,7 @@ http://secondlife.com/support for help fixing this problem.
<string name="ManageEstateSilently">Manage your estates silently</string>
<string name="ChangeYourDefaultAnimations">Change your default animations</string>
<string name="ForceSitAvatar">Force your avatar to sit</string>
+ <string name="ChangeEnvSettings">Change your environment settings</string>
<string name="NotConnected">Not Connected</string>
<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
@@ -2276,9 +2296,10 @@ For AI Character: Get the closest navigable point to the point provided.
<!-- inventory -->
<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
- <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
- <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
- <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
+ <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
+ <string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>
+ <string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string>
+ <string name="MarketplaceNoListing">You have no listings yet.</string>
<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string>
@@ -2351,6 +2372,8 @@ If you continue to receive this message, please contact Second Life support for
<string name="MarketplaceNoStock">out of stock</string>
<string name="MarketplaceUpdating">updating...</string>
+ <string name="UploadFeeInfo">Fee is based on your subscription level. Higher levels are charged lower fees. [https://secondlife.com/my/account/membership.php? Learn more]</string>
+
<string name="Open landmarks">Open landmarks</string>
<string name="Unconstrained">Unconstrained</string>
@@ -2395,6 +2418,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Scripts" value=" Scripts," />
<string name="Sounds" value=" Sounds," />
<string name="Textures" value=" Textures," />
+ <string name="Settings" value=" Settings," />
<string name="Snapshots" value=" Snapshots," />
<string name="No Filters" value="No " />
<string name="Since Logoff" value=" - Since Logoff" />
@@ -2765,6 +2789,14 @@ If you continue to receive this message, please contact Second Life support for
<string name="LocalSettings">Local Settings</string>
<string name="RegionSettings">Region Settings</string>
+ <string name="NoEnvironmentSettings">This Region does not support environmental settings.</string>
+ <string name="EnvironmentSun">Sun</string>
+ <string name="EnvironmentMoon">Moon</string>
+ <string name="EnvironmentBloom">Bloom</string>
+ <string name="EnvironmentCloudNoise">Cloud Noise</string>
+ <string name="EnvironmentNormalMap">Normal Map</string>
+ <string name="EnvironmentTransparent">Transparent</string>
+
<!-- panel classified -->
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
@@ -2804,10 +2836,9 @@ If you continue to receive this message, please contact Second Life support for
<string name="AcquiredItems">Acquired Items</string>
<string name="Cancel">Cancel</string>
<string name="UploadingCosts">Uploading [NAME] costs L$ [AMOUNT]</string>
- <string name="BuyingCosts">Buying this costs L$ [AMOUNT]</string>
<string name="UnknownFileExtension">
Unknown file extension .%s
-Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
+Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim
</string>
<string name="MuteObject2">Block</string>
<string name="MuteAvatar">Block</string>
@@ -3663,10 +3694,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Also there are some other places where "generic" is used.
So, let add string with name="generic" with the same value as "generic_request_error" -->
<string name="generic">
- Error making request, please try again later.
+ Please close and reopen the conversation, or relog and try again.
</string>
<string name="generic_request_error">
- Error making request, please try again later.
+ Please close and reopen the conversation, or relog and try again.
</string>
<string name="insufficient_perms_error">
You do not have sufficient permissions.
@@ -3728,6 +3759,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="unread_chat_multiple">
[SOURCES] have said something new
</string>
+ <string name="teleport_preamble_compact_chat">
+ You are now at
+ </string>
<string name="session_initialization_timed_out_error">
The session initialization is timed out
</string>
@@ -3737,6 +3771,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string>
<string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string>
+ <string name="lindenhomes_get_home_url">https://secondlife.com/land/lindenhomes/member.php</string>
+ <string name="lindenhomes_my_home_url">https://land.secondlife.com/en-Us/lindenhomes/my-home.php</string>
+ <string name="membership_url">https://secondlife.com/my/account/membership.php</string>
+
<!-- Financial operations strings -->
<string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>
<string name="paid_you_ldollars_gift">[NAME] paid you L$[AMOUNT]: [REASON]</string>
@@ -3760,11 +3798,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="to upload">to upload</string>
<string name="to publish a classified ad">to publish a classified ad</string>
- <string name="giving">Giving L$ [AMOUNT]</string>
<string name="uploading_costs">Uploading costs L$ [AMOUNT]</string>
<string name="this_costs">This costs L$ [AMOUNT]</string>
- <string name="buying_selected_land">Buying selected land for L$ [AMOUNT]</string>
- <string name="this_object_costs">This object costs L$ [AMOUNT]</string>
+
+ <string name="buying_selected_land">This land costs</string>
+ <string name="this_object_costs">This item costs</string>
+ <string name="giving">You want to give</string>
<string name="group_role_everyone">Everyone</string>
<string name="group_role_officers">Officers</string>
@@ -3837,6 +3876,12 @@ Abuse Report</string>
<string name="Female - Stick tougue out">Female - Stick tongue out</string>
<string name="Female - Wow">Female - Wow</string>
+<!-- settings -->
+ <string name="New Daycycle">New Daycycle</string>
+ <string name="New Water">New Water</string>
+ <string name="New Sky">New Sky</string>
+
+
<string name="/bow">/bow</string>
<string name="/clap">/clap</string>
<string name="/count">/count</string>
@@ -3914,6 +3959,15 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
<string name="Accounting">Accounting</string>
<string name="Notices">Notices</string>
<string name="Chat">Chat</string>
+
+ <!-- SL Membership -->
+ <string name="BaseMembership">Base</string>
+ <string name="PremiumMembership">Premium</string>
+ <string name="Premium PlusMembership">Premium Plus</string>
+ <string name="InternalMembership">Internal</string> <!-- No need to translate -->
+
+ <string name="MembershipUpgradeText">Upgrade to Premium</string>
+ <string name="MembershipPremiumText">My Premium membership</string>
<!-- Question strings for delete items notifications -->
<string name="DeleteItems">Delete selected items?</string>
@@ -4048,6 +4102,15 @@ Try enclosing path to the editor with double quotes.
<string name="Z">Z</string>
<!-- Key names end -->
+ <!-- Mouse button names (short) begin -->
+ <string name="LMB">LMB</string>
+ <string name="MMB">MMB</string>
+ <string name="RMB">RMB</string>
+ <string name="MB4">MB4</string>
+ <string name="MB5">MB5</string>
+ <string name="Double LMB">Double LMB</string>
+ <!-- Mouse button names end -->
+
<!-- llviewerwindow -->
<string name="BeaconParticle">Viewing particle beacons (blue)</string>
<string name="BeaconPhysical">Viewing physical object beacons (green)</string>
@@ -4055,28 +4118,30 @@ Try enclosing path to the editor with double quotes.
<string name="BeaconScriptedTouch">Viewing scripted object with touch function beacons (red)</string>
<string name="BeaconSound">Viewing sound beacons (yellow)</string>
<string name="BeaconMedia">Viewing media beacons (white)</string>
+ <string name="BeaconSun">Viewing sun direction beacon (orange)</string>
+ <string name="BeaconMoon">Viewing moon direction beacon (purple)</string>
<string name="ParticleHiding">Hiding Particles</string>
<!-- commands -->
<string name="Command_AboutLand_Label">About land</string>
- <string name="Command_Appearance_Label">Appearance</string>
- <string name="Command_Avatar_Label">Avatar</string>
+ <string name="Command_Appearance_Label">Outfits</string>
+ <string name="Command_Avatar_Label">Complete avatars</string>
<string name="Command_Build_Label">Build</string>
<string name="Command_Chat_Label">Chat</string>
<string name="Command_Conversations_Label">Conversations</string>
<string name="Command_Compass_Label">Compass</string>
<string name="Command_Destinations_Label">Destinations</string>
+ <string name="Command_Environments_Label">My Environments</string>
<string name="Command_Gestures_Label">Gestures</string>
<string name="Command_Grid_Status_Label">Grid status</string>
- <string name="Command_HowTo_Label">How to</string>
+ <string name="Command_HowTo_Label">Guidebook</string>
<string name="Command_Inventory_Label">Inventory</string>
<string name="Command_Map_Label">Map</string>
<string name="Command_Marketplace_Label">Marketplace</string>
<string name="Command_MarketplaceListings_Label">Marketplace</string>
<string name="Command_MiniMap_Label">Mini-map</string>
<string name="Command_Move_Label">Walk / run / fly</string>
- <string name="Command_Outbox_Label">Merchant outbox</string>
<string name="Command_People_Label">People</string>
<string name="Command_Picks_Label">Picks</string>
<string name="Command_Places_Label">Places</string>
@@ -4097,6 +4162,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Tooltip">Converse with everyone</string>
<string name="Command_Compass_Tooltip">Compass</string>
<string name="Command_Destinations_Tooltip">Destinations of interest</string>
+ <string name="Command_Environments_Tooltip">My Environments</string>
<string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
<string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
<string name="Command_HowTo_Tooltip">How to do common tasks</string>
@@ -4106,7 +4172,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_MarketplaceListings_Tooltip">Sell your creation</string>
<string name="Command_MiniMap_Tooltip">Show nearby people</string>
<string name="Command_Move_Tooltip">Moving your avatar</string>
- <string name="Command_Outbox_Tooltip">Transfer items to your marketplace for sale</string>
<string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
<string name="Command_Places_Tooltip">Places you've saved</string>
@@ -4172,6 +4237,8 @@ Try enclosing path to the editor with double quotes.
<string name="ExperiencePermission10">control your camera</string>
<string name="ExperiencePermission11">teleport you</string>
<string name="ExperiencePermission12">automatically accept experience permissions</string>
+ <string name="ExperiencePermission16">force your avatar to sit</string>
+ <string name="ExperiencePermission17">change your environment settings</string>
<string name="ExperiencePermissionShortUnknown">perform an unknown operation: [Permission]</string>
<string name="ExperiencePermissionShort1">Take Controls</string>
<string name="ExperiencePermissionShort3">Trigger Animations</string>
@@ -4180,6 +4247,8 @@ Try enclosing path to the editor with double quotes.
<string name="ExperiencePermissionShort10">Control Camera</string>
<string name="ExperiencePermissionShort11">Teleport</string>
<string name="ExperiencePermissionShort12">Permission</string>
+ <string name="ExperiencePermissionShort16">Sit</string>
+ <string name="ExperiencePermissionShort17">Environment</string>
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index 57f8bb542d..1456114b25 100644
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -2,8 +2,7 @@
<teleport_messages>
<message_set name="errors">
<message name="invalid_tport">
- Problem encountered processing your teleport request. You may need to log back in before you can teleport.
-If you continue to get this message, please check the [SUPPORT_SITE].
+ Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again.
</message>
<message name="invalid_region_handoff">
Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
diff --git a/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml b/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml
new file mode 100644
index 0000000000..0f3f0159db
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<densityctrl
+ border="true"
+ follows="all"
+ label="Density"
+ name="density_ctrl"
+ layout="topleft"
+ left="0"
+ top="0"
+ width="320"
+ height="240">
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ left="15"
+ top_pad="-5"
+ width="120">
+Exponential Term
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="0"
+ max_val="1"
+ name="level_exponential"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+
+ <view
+ left_pad="15"
+ top="15"
+ name="preview_image"
+ height="140"
+ width="140"
+ follows="left|top"
+ />
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ left="15"
+ top_pad="-5"
+ width="120">
+Exponential Scale Factor
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="0"
+ max_val="1"
+ name="exponential_scale"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ left="15"
+ top_pad="-5"
+ width="120">
+Linear Term
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="0"
+ max_val="1"
+ name="level_linear"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ left="15"
+ top_pad="-5"
+ width="120">
+Constant Term
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="0"
+ max_val="1"
+ name="level_constant"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ left="15"
+ top_pad="15"
+ width="80">
+Max Altitude
+ </text>
+ <slider
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="1000"
+ max_val="40000"
+ name="max_altitude"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+
+ <text
+ follows="left|top"
+ height="11"
+ layout="topleft"
+ name="aniso_factor_label"
+ left="15"
+ top_pad="15"
+ width="80">
+Anisotropy Factor
+ </text>
+ <slider
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="1"
+ initial_value="0"
+ layout="topleft"
+ left="15"
+ min_val="1000"
+ max_val="40000"
+ name="aniso_factor"
+ top_delta="15"
+ width="200"
+ can_edit_text="true"/>
+</densityctrl>
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index 2cc4abdd30..1c4822b8d5 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -6,9 +6,11 @@
text_pad_left="7"
select_on_focus="true"
text_tentative_color="TextFgTentativeColor"
+ highlight_text_field="false"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
- background_image_focused="TextField_Search_Active">
+ background_image_focused="TextField_Search_Active"
+ background_image_highlight="TextField_Search_Highlight">
<search_button label=""
top_pad="4"
left_pad="4"
diff --git a/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml b/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml
new file mode 100644
index 0000000000..a190da3909
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/joystick_quat.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<joystick_rotate
+ image_selected="Cam_Rotate_In"
+ image_unselected="Cam_Rotate_Out"
+ scale_image="false"
+ mouse_opaque="false"
+ held_down_delay.seconds="0"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
index a190da3909..cbf721b346 100644
--- a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
+++ b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<joystick_rotate
+<joystick_quat
image_selected="Cam_Rotate_In"
image_unselected="Cam_Rotate_Out"
- scale_image="false"
+ scale_image="true"
mouse_opaque="false"
held_down_delay.seconds="0"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
index a054960bf8..f39e086196 100644
--- a/indra/newview/skins/default/xui/en/widgets/line_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
@@ -6,6 +6,7 @@
commit_on_focus_lost="true"
ignore_tab="true"
cursor_color="TextCursorColor"
+ bg_color="White"
text_color="TextFgColor"
text_pad_left="2"
text_readonly_color="TextFgReadOnlyColor"
diff --git a/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml b/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
index 98707b8495..564f695cd0 100644
--- a/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
@@ -15,7 +15,7 @@
top="30"
scale_image="true"
visible="false"
- width="212" />
+ width="30" />
<panel_camera_item.icon_selected
follows="top|left"
height="30"
@@ -27,7 +27,7 @@
top="30"
scale_image="true"
visible="false"
- width="212" />
+ width="30" />
<panel_camera_item.picture
follows="top|left"
height="30"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index faa0404b35..dc5a07bf4f 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -7,9 +7,11 @@
text_pad_right="6"
select_on_focus="true"
text_tentative_color="TextFgTentativeColor"
+ highlight_text_field="false"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
- background_image_focused="TextField_Search_Active" >
+ background_image_focused="TextField_Search_Active"
+ background_image_highlight="TextField_Search_Highlight">
<search_button
top_pad="4"
left_pad="4"
diff --git a/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml
new file mode 100644
index 0000000000..9fa77855c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<sun_moon_trackball
+ name="virtualtrackball"
+ width="150"
+ height="150"
+ user_resize="false"
+ increment_angle_mouse="1.5f"
+ increment_angle_btn="1.0f"
+ image_sphere="VirtualTrackball_Sphere"
+ image_moon_back="VirtualTrackball_Moon_Back"
+ image_moon_front="VirtualTrackball_Moon_Front"
+ image_sun_back="VirtualTrackball_Sun_Back"
+ image_sun_front="VirtualTrackball_Sun_Front">
+
+ <sun_moon_trackball.border
+ visible="true"/>
+
+ <sun_moon_trackball.labelN
+ font="SansSerif"
+ name="labelN"
+ valign="bottom"
+ halign="left"
+ label="N"/>
+ <sun_moon_trackball.labelS
+ font="SansSerif"
+ name="labelS"
+ valign="top"
+ halign="left"
+ label="S"/>
+ <sun_moon_trackball.labelW
+ font="SansSerif"
+ name="labelW"
+ valign="top"
+ halign="right"
+ label="W"/>
+ <sun_moon_trackball.labelE
+ font="SansSerif"
+ name="labelE"
+ valign="top"
+ halign="left"
+ label="E"/>
+
+ <sun_moon_trackball.button_rotate_top
+ name="btn_rotate_top"
+ image_unselected="VirtualTrackball_Rotate_Top"
+ image_selected="VirtualTrackball_Rotate_Top_Active"
+ image_disabled="Blank" />
+
+ <sun_moon_trackball.button_rotate_bottom
+ name="btn_rotate_bottom"
+ image_unselected="VirtualTrackball_Rotate_Bottom"
+ image_selected="VirtualTrackball_Rotate_Bottom_Active"
+ image_disabled="Blank" />
+
+ <sun_moon_trackball.button_rotate_left
+ name="btn_rotate_left"
+ image_unselected="VirtualTrackball_Rotate_Left"
+ image_selected="VirtualTrackball_Rotate_Left_Active"
+ image_disabled="Blank" />
+
+ <sun_moon_trackball.button_rotate_right
+ name="btn_rotate_right"
+ image_unselected="VirtualTrackball_Rotate_Right"
+ image_selected="VirtualTrackball_Rotate_Right_Active"
+ image_disabled="Blank" />
+
+</sun_moon_trackball>
+
diff --git a/indra/newview/skins/default/xui/en/widgets/xy_vector.xml b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml
new file mode 100644
index 0000000000..93ae26a6ad
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xy_vector
+ name="xyvector"
+ width="120"
+ height="140"
+ decimal_digits="1"
+ label_width="16"
+ padding="4"
+ edit_bar_height="18"
+ user_resize="false">
+
+ <xy_vector.border
+ visible="true"/>
+
+ <xy_vector.x_entry
+ name="XEntry"
+ tab_stop="true"
+ label="X:"/>
+ <xy_vector.y_entry
+ name="YEntry"
+ tab_stop="true"
+ label="Y:"/>
+
+ <xy_vector.touch_area
+ name="TouchArea"
+ bevel_style="in"
+ border_visible="true"/>
+
+</xy_vector>
diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml
index 998d2a8863..df0edd498f 100644
--- a/indra/newview/skins/default/xui/es/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_about_land.xml
@@ -362,7 +362,7 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
Foto:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Pulse para elegir una imagen"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Los avatares de otras parcelas pueden ver a los avatares de esta parcela y chatear con ellos
</text>
<check_box label="Ver los avatares" name="SeeAvatarsCheck" tool_tip="Permite que los avatares de otras parcelas vean a los avatares de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos." top="170"/>
@@ -444,7 +444,7 @@ los media:
<panel.string name="estate_override">
Una o más de esta opciones está configurada a nivel del estado
</panel.string>
- <check_box label="Cualquiera puede visitar (Si no seleccionas esta opción, se crearán líneas de prohibición)" name="public_access"/>
+ <check_box label="Cualquiera puede visitar" name="public_access" tool_tip="Si no seleccionas esta opción, se crearán líneas de prohibición"/>
<check_box label="Debe ser mayor de 18 [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/>
<check_box label="Debe haber información archivada sobre el pago [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Para poder acceder a esta parcela los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/>
<check_box label="Permitir grupo [GROUP] sin restricciones" name="GroupCheck" tool_tip="Elija el grupo en la pestaña General."/>
@@ -479,5 +479,6 @@ los media:
</panel>
</panel>
<panel label="EXPERIENCIAS" name="land_experiences_panel"/>
+ <panel label="ENTORNO" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_adjust_environment.xml b/indra/newview/skins/default/xui/es/floater_adjust_environment.xml
new file mode 100644
index 0000000000..25b6fad165
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Iluminación personal">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Restablecer" name="btn_reset" tool_tip="Cerrar y restablecer Entorno compartido"/>
+ <text name="cloud_map_label">
+ Imagen nube:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Sol:
+ </text>
+ <check_box label="Mostrar baliza" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Mostrar baliza" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_beacons.xml b/indra/newview/skins/default/xui/es/floater_beacons.xml
index 49f990c84d..0eabcc7c27 100644
--- a/indra/newview/skins/default/xui/es/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/es/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Origen de sonidos" name="sounds"/>
<check_box label="Origen de partículas" name="particles"/>
<check_box label="Fuentes de media" name="moapbeacon"/>
+ <check_box label="Sol" name="sun"/>
+ <check_box label="Luna" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_bulk_perms.xml b/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
index 75e324c7ef..5ab13d2b09 100644
--- a/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="Sonidos"/>
<check_box label="Texturas" name="check_texture"/>
<icon name="icon_texture" tool_tip="Texturas"/>
+ <icon name="icon_setting" tool_tip="Configuración de entorno"/>
<button label="√ Todos" label_selected="Todo" name="check_all"/>
<button label="Limpiar" label_selected="Ninguno" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency.xml b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
index 2c8848265f..086150dd57 100644
--- a/indra/newview/skins/default/xui/es/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
@@ -60,8 +60,7 @@ no el objeto.
</text>
<button label="Comprar ahora" name="buy_btn"/>
<button label="Cancelar" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5">
+ <floater.string name="info_cannot_buy">
No se pudo hacer la compra
- </text>
- <button label="Ir a la web" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
deleted file mode 100644
index bd0910e5d4..0000000000
--- a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="ELIMINAR EL ENV PREDEFINIDO">
- <string name="title_water">
- Eliminar el agua predefinida
- </string>
- <string name="title_sky">
- Eliminar cielo predefinido
- </string>
- <string name="title_day_cycle">
- Eliminar ciclo del día
- </string>
- <string name="label_water">
- Predefinido:
- </string>
- <string name="label_sky">
- Predefinido:
- </string>
- <string name="label_day_cycle">
- Ciclo del día:
- </string>
- <string name="msg_confirm_deletion">
- ¿Estás seguro de que quieres eliminar el valor predefinido seleccionado?
- </string>
- <string name="msg_sky_is_referenced">
- No se puede quitar un valor predefinido al que se hace referencia en otro u otros ciclos del día.
- </string>
- <string name="combo_label">
- -Selecciona un valor predefinido-
- </string>
- <text name="label">
- Predefinido:
- </text>
- <button label="Eliminar" name="delete"/>
- <button label="Cancelar" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/es/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..c3273ea64e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Editar Ciclo del día">
+ <string name="title_new">
+ Crear un Nuevo ciclo del día
+ </string>
+ <string name="title_edit">
+ Editar Ciclo del día
+ </string>
+ <string name="hint_new">
+ Asigna un nombre al ciclo del día, ajusta los controles para crearlo y selecciona &quot;Guardar&quot;.
+ </string>
+ <string name="hint_edit">
+ Para editar el ciclo del día, ajusta los controles siguientes y selecciona &quot;Guardar&quot;.
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Cielo [ALT]
+ </string>
+ <string name="sky_label">
+ Cielo
+ </string>
+ <string name="water_label">
+ Agua
+ </string>
+ <string name="commit_parcel">
+ Aplicar a la Parcela
+ </string>
+ <string name="commit_region">
+ Aplicar a la Región
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Nombre del Ciclo del día:
+ </text>
+ <button label="Importar" name="btn_import" tool_tip="Importar configuración legado desde disco."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Cielo 4" name="sky4_track"/>
+ <button label="Cielo 3" name="sky3_track"/>
+ <button label="Cielo 2" name="sky2_track"/>
+ <button label="Nivel del terreno" name="sky1_track"/>
+ <button label="Agua" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0 %[DSC]"/>
+ <text name="p1" value="25 %[DSC]"/>
+ <text name="p2" value="50 %[DSC]"/>
+ <text name="p3" value="75 %[DSC]"/>
+ <text name="p4" value="100 %[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Clonar ruta de" name="copy_track"/>
+ <button label="Cargar ruta de" name="load_track"/>
+ <button label="Borrar ruta" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Ir hacia atrás"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Ir hacia adelante"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="Añadir [FRAME]" name="add_frame"/>
+ <button label="Cargar [FRAME]" name="btn_load_frame"/>
+ <button label="Borrar [FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Seleccionar un marco clave de la línea de tiempo indicada arriba para editar los parámetros.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Agua" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmósfera e Iluminación" name="atmosphere_panel"/>
+ <panel label="Nubes" name="clouds_panel"/>
+ <panel label="Sol y Luna" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Guardar" name="save_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/es/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..d17dcaad01
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Entorno fijo">
+ <string name="edit_sky">
+ Editar Cielo:
+ </string>
+ <string name="edit_water">
+ Editar Agua:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Cargar" name="btn_load" tool_tip="Cargar una configuración del inventario"/>
+ <button label="Importar" name="btn_import" tool_tip="Importar configuración legado desde disco."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Guardar" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Cancelar" name="btn_cancel" tool_tip="Volver a la última versión guardada"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
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 5698e39bee..4f3c177976 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
@@ -12,6 +12,7 @@
<check_box label="Sonidos" name="check_sound"/>
<check_box label="Texturas" name="check_texture"/>
<check_box label="Fotos" name="check_snapshot"/>
+ <check_box label="Opciones" name="check_settings"/>
<button label="Todos" label_selected="Todo" name="All"/>
<button label="Ninguno" label_selected="Nada" name="None"/>
<check_box label="Mostrar siempre las carpetas" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
deleted file mode 100644
index b74c5fca5c..0000000000
--- a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="BUZÓN DE SALIDA DE COMERCIANTE">
- <string name="OutboxFolderCount1">
- 1 carpeta
- </string>
- <string name="OutboxFolderCountN">
- [NUM] carpetas
- </string>
- <string name="OutboxImporting">
- Enviando carpetas...
- </string>
- <string name="OutboxInitializing">
- Inicializando...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Cargando...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Arrastra aquí artículos para crear carpetas
- </text>
- </panel>
- <button label="Enviar al Mercado" name="outbox_import_btn" tool_tip="Poner en el escaparate de Mi Mercado"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_my_environments.xml b/indra/newview/skins/default/xui/es/floater_my_environments.xml
new file mode 100644
index 0000000000..8f636490ac
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Lugares" name="my_environments" title="MIS ENTORNOS">
+ <layout_stack>
+ <layout_panel label="Filtros" name="filter_panel">
+ <check_box label="Días" name="chk_days"/>
+ <check_box label="Cielos" name="chk_skies"/>
+ <check_box label="Agua" name="chk_water"/>
+ <filter_editor label="Filtrar entornos" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Entornos" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Mostrar todas las carpetas" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Más opciones"/>
+ <menu_button name="btn_newsettings" tool_tip="Crear una opción nueva"/>
+ <button name="btn_del" tool_tip="Quitar el ítem seleccionado"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_perms_default.xml b/indra/newview/skins/default/xui/es/floater_perms_default.xml
index 97e5390931..7238ee7716 100644
--- a/indra/newview/skins/default/xui/es/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/es/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Definir los permisos predeterminados para la creación de ropa o partes del cuerpo">
Artículos de vestir
</text>
+ <text name="label_13" tool_tip="Definir los permisos predeterminados para la creación de parámetros de entorno">
+ Opciones
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Cancelar" label_selected="Cancelar" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/es/floater_pick_track.xml b/indra/newview/skins/default/xui/es/floater_pick_track.xml
new file mode 100644
index 0000000000..44c24248a6
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="DESTACADO: RUTA">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Seleccionar cielo fuente:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Cielo4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Cielo3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Cielo2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Terreno" name="radio_sky1" value="1."/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Cancelar" label_selected="Cancelar" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml
index b8d5824fb7..2bcec020b2 100644
--- a/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/es/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Agua transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Efecto de relieve y brillo" name="BumpShiny"/>
<check_box initial_value="true" label="Puntos de luz locales" name="LocalLights"/>
- <check_box initial_value="true" label="Shaders básicos" name="BasicShaders" tool_tip="Desactivar esta opción puede evitar que se bloqueen los controladores de algunas tarjetas gráficas"/>
<slider label="Nivel de detalle del terreno:" name="TerrainDetail"/>
<text name="TerrainDetailText">
Bajo
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 4012191c78..b0afd44750 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
@@ -10,7 +10,7 @@
Descripción:
</text>
<text name="dimensions">
- [WIDTH] px x [HEIGHT] px
+ [WIDTH]px x [HEIGHT]px
</text>
<text name="aspect_ratio">
Previsualizar la ratio de las proporciones
diff --git a/indra/newview/skins/default/xui/es/floater_settings_picker.xml b/indra/newview/skins/default/xui/es/floater_settings_picker.xml
new file mode 100644
index 0000000000..73b8de30c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="DESTACADO: CONFIGURACIÓN">
+ <floater.string name="pick title">
+ Destacado:
+ </floater.string>
+ <floater.string name="pick_track">
+ SELECCIONAR RUTA
+ </floater.string>
+ <floater.string name="pick_settings">
+ SELECCIONAR CONFIGURACIÓN
+ </floater.string>
+ <floater.string name="track_water">
+ Agua
+ </floater.string>
+ <floater.string name="track_ground">
+ Terreno
+ </floater.string>
+ <floater.string name="track_sky">
+ Cielo[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Filtrar las texturas" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Cancelar" label_selected="Cancelar" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
index 01b024bc3e..a77dd99af0 100644
--- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
@@ -9,18 +9,14 @@
<text name="Multiple">
Texturas múltiples
</text>
- <radio_group name="mode_selection">
- <radio_item label="Inventario" name="inventory" value="0"/>
- <radio_item label="Local" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Tamaño: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Inventario" name="inventory" value="0"/>
+ <combo_box.item label="Local" name="local" value="1"/>
+ </combo_box>
<button label="Por defecto" label_selected="Por defecto" name="Default" width="84"/>
<button label="Blanca" label_selected="Blanca" name="Blank"/>
<button label="Ninguna" label_selected="Ninguna" left="90" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <check_box initial_value="true" label="Aplicarlo ahora" name="apply_immediate_check"/>
<text name="preview_disabled" value="Vista previa inhabilitada"/>
<filter_editor label="Filtrar las texturas" name="inventory search editor"/>
<check_box initial_value="false" label="Ver las carpetas" name="show_folders_check"/>
@@ -31,6 +27,22 @@
<column label="Nombre" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Elegir la textura de horneado">
+ <combo_box.item label="Ninguno" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Esconder Región Malla Base" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
+ <check_box initial_value="true" label="Aplicarlo ahora" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
index 7541530601..65e31c0654 100644
--- a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Tocar" name="touch_attach" />
+ <menu_item_call label="Editar" name="edit_item" />
<menu_item_call label="Quitar" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml
index c5bc301608..d855d6f04f 100644
--- a/indra/newview/skins/default/xui/es/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Activar" name="Marketplace Activate"/>
<menu_item_call label="Desactivar" name="Marketplace Deactivate"/>
<menu_item_call label="Compartir" name="Share"/>
- <menu_item_call label="Comprar" name="Task Buy"/>
<menu_item_call label="Abrir" name="Task Open"/>
<menu_item_call label="Ejecutar" name="Task Play"/>
<menu_item_call label="Propiedades" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Ropa interior nueva" name="New Underpants"/>
<menu_item_call label="Nueva capa Alpha" name="New Alpha Mask"/>
<menu_item_call label="Tatuaje nuevo" name="New Tattoo"/>
+ <menu_item_call label="Nuevo Universal" name="New Universal"/>
<menu_item_call label="Nueva física" name="New Physics"/>
</menu>
<menu label="Nuevas partes del cuerpo" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Pelo nuevo" name="New Hair"/>
<menu_item_call label="Ojos nuevos" name="New Eyes"/>
</menu>
+ <menu label="Nueva Configuración" name="New Settings">
+ <menu_item_call label="Nuevo Cielo" name="New Sky"/>
+ <menu_item_call label="Nueva Agua" name="New Water"/>
+ <menu_item_call label="Nuevo Ciclo del día" name="New Day Cycle"/>
+ </menu>
<menu label="Usar como valor predeterminado para" name="upload_def">
<menu_item_call label="Imágenes subidas" name="Image uploads"/>
<menu_item_call label="Sonidos subidos" name="Sound uploads"/>
@@ -99,9 +104,12 @@
<menu_item_call label="Ponerme" name="Wearable And Object Wear"/>
<menu label="Anexar a" name="Attach To"/>
<menu label="Anexar como HUD" name="Attach To HUD"/>
+ <menu_item_call label="Tocar" name="Attachment Touch" />
<menu_item_call label="Editar" name="Wearable Edit"/>
<menu_item_call label="Añadir" name="Wearable Add"/>
<menu_item_call label="Quitarse" name="Take Off"/>
+ <menu_item_call label="Aplicar sólo a Mi mismo" name="Settings Apply Local"/>
+ <menu_item_call label="Aplicar a la Parcela" name="Settings Apply Parcel"/>
<menu_item_call label="Copiar en artículos del Mercado" name="Marketplace Copy"/>
<menu_item_call label="Mover a artículos del Mercado" name="Marketplace Move"/>
<menu_item_call label="--sin opciones--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory_add.xml b/indra/newview/skins/default/xui/es/menu_inventory_add.xml
index f17cfe4ceb..f9a9f3a9fe 100644
--- a/indra/newview/skins/default/xui/es/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Sonido ([COST] L$)..." name="Upload Sound"/>
<menu_item_call label="Animación ([COST] L$)..." name="Upload Animation"/>
<menu_item_call label="Modelo..." name="Upload Model"/>
- <menu_item_call label="Asistente de modelo..." name="Upload Model Wizard"/>
<menu_item_call label="Masivo ([COST] L$ por archivo)..." name="Bulk Upload"/>
- <menu_item_call label="Configurar los permisos por defecto de subida" name="perm prefs"/>
</menu>
<menu_item_call label="Carpeta nueva" name="New Folder"/>
<menu_item_call label="Script nuevo" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Ropa interior nueva" name="New Underpants"/>
<menu_item_call label="Nueva Alfa" name="New Alpha"/>
<menu_item_call label="Tatuaje nuevo" name="New Tattoo"/>
+ <menu_item_call label="Nuevo Universal" name="New Universal"/>
<menu_item_call label="Nueva física" name="New Physics"/>
</menu>
<menu label="Nuevas partes del cuerpo" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Pelo nuevo" name="New Hair"/>
<menu_item_call label="Ojos nuevos" name="New Eyes"/>
</menu>
+ <menu label="Nueva Configuración" name="New Settings">
+ <menu_item_call label="Nuevo Cielo" name="New Sky"/>
+ <menu_item_call label="Nueva Agua" name="New Water"/>
+ <menu_item_call label="Nuevo Ciclo del día" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
index b3f2b789d7..0cfab7ffc8 100644
--- a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Nueva Alfa" name="New Alpha"/>
<menu_item_call label="Nueva física" name="New Physics"/>
<menu_item_call label="Tatuaje nuevo" name="New Tattoo"/>
+ <menu_item_call label="Nuevo Universal" name="New Universal"/>
</menu>
<menu label="Nuevas partes del cuerpo" name="New Body Parts">
<menu_item_call label="Anatomía nueva" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/es/menu_save_settings.xml b/indra/newview/skins/default/xui/es/menu_save_settings.xml
new file mode 100644
index 0000000000..164763427d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Guardar" name="save_settings"/>
+ <menu_item_check label="Guardar como" name="save_as_new_settings"/>
+ <menu_item_check label="Asignar" name="commit_changes"/>
+ <menu_item_check label="Aplicar sólo a Mi mismo" name="apply_local"/>
+ <menu_item_check label="Aplicar a la Parcela" name="apply_parcel"/>
+ <menu_item_check label="Aplicar a la Región" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_settings_add.xml b/indra/newview/skins/default/xui/es/menu_settings_add.xml
new file mode 100644
index 0000000000..82bd384ab5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Nuevo Cielo" name="New Sky"/>
+ <menu_item_call label="Nueva Agua" name="New Water"/>
+ <menu_item_call label="Nuevo Ciclo del día" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_settings_gear.xml b/indra/newview/skins/default/xui/es/menu_settings_gear.xml
new file mode 100644
index 0000000000..5d1b43933f
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Editar" name="edit_settings"/>
+ <menu_item_call label="Aplicar sólo a Mi mismo" name="Settings Apply Local"/>
+ <menu_item_call label="Aplicar a la Parcela" name="Settings Apply Parcel"/>
+ <menu_item_call label="Aplicar a la Región" name="Settings Apply Region"/>
+ <menu_item_call label="Copiar" name="copy_settings"/>
+ <menu_item_call label="Pegar" name="paste_settings"/>
+ <menu_item_call label="Copiar la UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 7cc3c0320a..10955567ba 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="Propiedades de la parcela" name="Parcel Properties"/>
<menu_item_check label="Menú Avanzado" name="Show Advanced Menu"/>
</menu>
- <menu label="Dom" name="Sun">
+ <menu label="Entorno" name="Environment">
<menu_item_check label="Amanecer" name="Sunrise"/>
<menu_item_check label="Mediodía" name="Noon"/>
<menu_item_check label="Atardecer" name="Sunset"/>
<menu_item_check label="Medianoche" name="Midnight"/>
- <menu_item_check label="Usar Configuración de la Región" name="Use Region Settings"/>
- </menu>
- <menu label="Editor de entorno" name="Environment Editor">
- <menu_item_call label="Configuración del entorno..." name="Environment Settings"/>
- <menu label="Agua predefinida" name="Water Presets">
- <menu_item_call label="Nuevo predefinido..." name="new_water_preset"/>
- <menu_item_call label="Editar predefinido..." name="edit_water_preset"/>
- <menu_item_call label="Eliminar predefinido..." name="delete_water_preset"/>
- </menu>
- <menu label="Cielos predefinidos" name="Sky Presets">
- <menu_item_call label="Nuevo predefinido..." name="new_sky_preset"/>
- <menu_item_call label="Editar predefinido..." name="edit_sky_preset"/>
- <menu_item_call label="Eliminar predefinido..." name="delete_sky_preset"/>
- </menu>
- <menu label="Días predefinidos" name="Day Presets">
- <menu_item_call label="Nuevo predefinido..." name="new_day_preset"/>
- <menu_item_call label="Editar predefinido..." name="edit_day_preset"/>
- <menu_item_call label="Eliminar predefinido..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Usar entorno compartido" name="Use Shared Environment"/>
+ <menu_item_call label="Mis entornos..." name="my_environs"/>
+ <menu_item_call label="Iluminación personal..." name="adjustment_tool"/>
+ <menu_item_check label="Pausar Nubes" name="pause_clouds"/>
</menu>
</menu>
<menu label="Construir" name="BuildTools">
@@ -323,6 +308,9 @@
<menu_item_check label="Capas alfa automáticas (no deferidas)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Animation Textures" name="Animation Textures"/>
<menu_item_check label="Disable Textures" name="Disable Textures"/>
+ <menu_item_check label="Desactivar ambiente" name="Disable Ambient"/>
+ <menu_item_check label="Desactivar luz del sol" name="Disable Sunlight"/>
+ <menu_item_check label="Desactivar luces locales" name="Disable Local Lights"/>
<menu_item_check label="Render Attached Lights" name="Render Attached Lights"/>
<menu_item_check label="Render Attached Particles" name="Render Attached Particles"/>
<menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/>
@@ -406,6 +394,7 @@
</menu>
<menu label="Admin" name="Deprecated">
<menu label="Take Off Clothing" name="Take Off Clothing">
+ <menu_item_call label="Universal" name="Universal"/>
<menu_item_call label="Física" name="Physics"/>
</menu>
<menu label="Ayuda" name="DeprecatedHelp">
diff --git a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
index 4bffa689e7..cb68ad39a4 100644
--- a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Reemplazar" name="wear_replace"/>
<menu_item_call label="Ponerme" name="wear_wear"/>
<menu_item_call label="Añadir" name="wear_add"/>
+ <menu_item_call label="Tocar" name="touch" />
<menu_item_call label="Quitarme / Quitar" name="take_off_or_detach"/>
<menu_item_call label="Quitar" name="detach"/>
<context_menu label="Anexar a" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
index ec13f99a01..01d1b16b58 100644
--- a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Editar el vestuario" name="edit"/>
+ <menu_item_call label="Tocar" name="touch"/>
+ <menu_item_call label="Editar" name="edit_item"/>
+ <menu_item_call label="Editar el vestuario" name="edit_outfit"/>
<menu_item_call label="Quitarme" name="takeoff"/>
<menu_item_call label="Copiar la lista del vestuario al portapapeles" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
index 637a14cf5b..54a7d9b92c 100644
--- a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Tocar" name="touch_attach"/>
<menu_item_call label="Quitarme" name="take_off"/>
<menu_item_call label="Quitar" name="detach"/>
- <menu_item_call label="Editar el vestuario" name="edit"/>
+ <menu_item_call label="Editar el vestuario" name="edit_outfit"/>
<menu_item_call label="Editar" name="edit_item"/>
<menu_item_call label="Mostrar original" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 0a3576b799..c7750320d5 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -265,6 +265,10 @@ La inicialización del mercado ha fallado por un error del sistema o de la red.
¿Quieres revocar los derechos de modificación a los residentes seleccionados?
<usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ El nombre de un grupo debe contener entre [MIN_LEN] y [MAX_LEN] caracteres.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
No se ha podido crear el grupo.
[MESSAGE]
@@ -356,7 +360,7 @@ Si no quieres que este rol siga teniendo dichas capacidades, deshabilítalas inm
No tienes dinero suficiente para entrar.
</notification>
<notification name="CreateGroupCost">
- Crear este grupo te costará 100 L$.
+ Crear este grupo costará L$[COST].
Los grupos necesitan más de un miembro. Si no, son borrados permanentemente.
Por favor, invita a miembros en las próximas 48 horas.
<usetemplate canceltext="Cancelar" name="okcancelbuttons" notext="Cancelar" yestext="Crear un grupo por 100 L$"/>
@@ -498,6 +502,9 @@ debes estar dentro de ella.
<notification name="ErrorEncodingSnapshot">
Error al codificar la foto.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Necesitas L$[COST] para subir este objeto.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Necesitas [COST] L$ para guardar una foto en el inventario. Puedes comprar L$ o bien guardar la foto en tu equipo.
</notification>
@@ -1745,11 +1752,14 @@ Haz clic en OK para instalar.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- El límite de grupos para las cuentas básicas es de [MAX_BASIC], y para
-las cuentas [https://secondlife.com/premium/ Premium] es de [MAX_PREMIUM].
-Si has bajado la categoría de tu cuenta, tendrás que estar por debajo del límite de [MAX_BASIC] grupos para poder apuntarte a más grupos.
-
-[https://secondlife.com/my/account/membership.php Cámbiate hoy a Premium]
+ Los residentes con membresías Básicas pueden unirse a hasta [MAX_BASIC] grupos.
+Las membresías Premium permiten hasta [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Aprende más al respecto o mejora tu membresía]
+ <usetemplate name="okbutton" yestext="Cerrar"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ Los residentes con membresías Básicas pueden unirse a hasta [MAX_BASIC] cinco grupos.
+Las membresías Premium permiten hasta [MAX_PREMIUM]. Las membresías Premium Plus permiten
+hasta [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Aprende más al respecto o mejora tu membresía]
<usetemplate name="okbutton" yestext="Cerrar"/>
</notification>
<notification name="KickUser">
@@ -1968,6 +1978,11 @@ Se cambiarán miles de regiones, y se provocará un colapso en el espacio del se
Si esta opción no está seleccionada, se anularán las restricciones establecidas por los dueños de parcelas para evitar provocaciones, mantener la privacidad o proteger a los residentes menores de material para adultos. Por favor, consulte con los dueños de parcelas según sea necesario.
<usetemplate name="okbutton" yestext="Aceptar"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Si esta opción no está seleccionada, se anularán los entornos personalizados añadidos por los dueños a sus parcelas. Por favor, consulta con los dueños de parcelas según sea necesario.
+¿Quieres seguir?
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
<usetemplate name="okbutton" yestext="OK"/>
@@ -2447,7 +2462,15 @@ Publícala en una página web para que otros puedan acceder fácilmente a esta p
Este archivo del ciclo de un día se refiere a un archivo perdido de cielo: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- No se pudo aplicar la configuración a la región. El problema podría solucionarse saliendo de la región y regresando a ella. La razón especificada fue: [FAIL_REASON]
+ No se pudo aplicar la configuración a la región. Motivo: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Una textura local está en uso en la ruta, [TRACK], # cuadro [FRAMENO] ([FRAME]%) en el campo [FIELD].
+Los parámetros no pueden guardarse usando texturas locales.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Una textura local está en uso en el campo [FIELD].
+Los parámetros no pueden guardarse usando texturas locales.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
No se puede eliminar la última clave de este ciclo del día, ya que no puedes vaciar la caché del día. En lugar de intentar eliminar la última clave restante y después intentar crear una nueva, debes modificarla.
@@ -3291,6 +3314,22 @@ Por tu seguridad, serán bloqueadas durante unos segundos.
Un moderador ha silenciado tu voz.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Desafortunadamente no fuimos capaces de obtener información sobre los beneficios para esta sesión. Esto no debería suceder en un espacio de producción normal. Por favor contacte con soporte. Esta sesión no funcionara normalmente y recomendamos reiniciar.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Esto subirá [COUNT] objetos por un costo total de L$[COST]. ¿Deseas continuar con la subida?
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Subir"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Los archivos seleccionados no pueden ser subidos en grupo.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Algunos de los archivos seleccionados no pueden ser subidos en grupo.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
Esta carga te costará [PRECIO] L$. ¿Deseas continuar?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Subir"/>
@@ -4387,4 +4426,76 @@ Prueba a seleccionar un terreno más pequeño.
[REASON]
<usetemplate name="okbutton" yestext="Aceptar"/>
</notification>
+ <notification name="FailedToFindSettings">
+ No se pudo cargar la configuración para [NAME] a partir de la base de datos.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ No se pudo aplicar esa configuración al entorno.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ No se pudo aplicar esa configuración al entorno.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Esta región no es compatible con las opciones de entorno.
+ </notification>
+ <notification label="Guardar el vestuario" name="SaveSettingAs">
+ Guardar parámetros de entorno actuales como:
+ <form name="form">
+ <input name="message">
+ [DESC] (nuevo)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Cancelar"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ No se pudo importar la configuración de Viento de luz legado [NAME] de
+[FILE].
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ No se pudo configurar el entorno para esta parcela.
+Por favor ingresa o selecciona una parcela cuyos derechos puedes modificar.
+ </notification>
+ <notification name="SettingsUnsuported">
+ La configuración de entorno no está disponible en esta región.
+Por favor accede a una región cuya configuración esté disponible y vuelve a intentar.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Estás a punto de perder los cambios que realizaste en este [TYPE] llamado &quot;[NAME]&quot;.
+¿Estás seguro de que deseas continuar?
+ <usetemplate ignoretext="¿Estás seguro de que quieres perder los cambios?" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Estás a punto de eliminar todos los parámetros aplicados.
+¿Estás seguro de que deseas continuar?
+ <usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Estás a punto de eliminar todos los parámetros aplicados de iluminación personal.
+¿Estás seguro de que deseas continuar?
+ <usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Estás a punto de importar parámetros no transferibles a este ciclo del día. Si continúas, las opciones que estás editando pasarán a ser no transferibles también.
+
+Este cambio no se puede deshacer.
+
+¿Estás seguro de que deseas continuar?
+ <usetemplate ignoretext="¿Estás seguro de que quieres que esta opción sea no transferible?" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ No puedes editar parámetros directamente en la librería.
+Por favor, copia a tu propio inventario y vuelve a intentarlo.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Se produjo un error con estos parámetros. No pueden guardarse o aplicarse por el momento.
+ </notification>
+ <notification name="TrackLoadFailed">
+ No se pudo cargar la ruta en [TRACK].
+ </notification>
+ <notification name="TrackLoadMismatch">
+ No se pudo cargar la ruta de [TRACK1] a [TRACK2].
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
index 8776dd6c10..6f6ee41e54 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Tatuaje de la cabeza" name="Head Tattoo" tool_tip="Pulsa para elegir una imagen"/>
- <texture_picker label="Tatuaje superior" name="Upper Tattoo" tool_tip="Pulsa para elegir una imagen"/>
- <texture_picker label="Tatuaje inferior" name="Lower Tattoo" tool_tip="Pulsa para elegir una imagen"/>
- <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Tatuaje en la cabeza" name="Head Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje superior" name="Upper Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje inferior" name="Lower Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_universal.xml b/indra/newview/skins/default/xui/es/panel_edit_universal.xml
new file mode 100644
index 0000000000..5c825b5980
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Tatuaje de la cabeza" name="Head Universal Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje superior" name="Upper Universal Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje inferior" name="Lower Universal Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje en falda" name="Skirt Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje en cabello" name="Hair Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje en ojos" name="Eyes Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje en brazo izquierdo" name="Left Arm Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje en pierna izquierda" name="Left Leg Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje Aux1" name="Aux1 Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje Aux2" name="Aux2 Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <texture_picker label="Tatuaje Aux3" name="Aux3 Tattoo" tool_tip="Pulsa para elegir una imagen"/>
+ <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_wearable.xml b/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
index 799512968d..c1edf99f87 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Modificando los tatuajes
</string>
+ <string name="edit_universal_title">
+ Modificando Universal
+ </string>
<string name="edit_physics_title">
Modificar la física
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Tatuaje:
</string>
+ <string name="universal_desc_text">
+ Universal:
+ </string>
<string name="physics_desc_text">
Física:
</string>
diff --git a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
deleted file mode 100644
index 9e2f3c3adc..0000000000
--- a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Arrastra y coloca aquí los objetos que desees preparar para venderlos en tu tienda"/>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 909743c325..73b9af3665 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -18,7 +18,7 @@
<string name="no_groups_msg" value="¿Buscas grupos en que participar? Prueba la [secondlife:///app/search/groups Búsqueda]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Pulsa dos veces para abrir el mapa, pulsa mayús y arrastra para obtener una panorámica)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Pulsa dos veces para teleportarte, pulsa mayús y arrastra para obtener una panorámica)"/>
- <string name="GroupCountWithInfo" value="Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más. [secondlife:/// ¿Quieres más?]"/>
+ <string name="GroupCountWithInfo" value="Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más. [secondlife:/// Incrementa tu límite]"/>
<tab_container name="tabs">
<panel label="CERCANA" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@
<dnd_button name="minus_btn" tool_tip="Dejar el grupo seleccionado"/>
</panel>
<text name="groupcount">
- Formas parte de [COUNT] grupos y puedes unirte a [REMAINING] más.
+ Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más.
</text>
</panel>
<panel label="RECIENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
index 007101b8fe..0ba676898f 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
@@ -28,5 +28,5 @@
<check_box label="Mostrar la selección de cuadrícula al iniciar sesión" name="show_grid_selection_check"/>
<check_box label="Mostrar el menú Avanzado" name="show_advanced_menu_check"/>
<check_box label="Mostrar el menú Desarrollar" name="show_develop_menu_check"/>
- <button label="Permisos de creación predeterminados" name="default_creation_permissions"/>
+ <button label="Permisos de creación predeterminados" name="default_creation_permissions" width="235"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index f7e036efd7..388a5d84d2 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Medio" name="Medium" value="1"/>
<item label="Grande" name="Large" value="2"/>
</combo_box>
- <check_box label="Bocadillos del chat" name="bubble_text_chat"/>
+ <check_box label="Bocadillos del chat" name="bubble_text_chat" left_delta="30"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
index 816c698548..47815d0296 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
</text>
<check_box initial_value="true" label="Renderizar siempre los amigos" name="AlwaysRenderFriends"/>
<button label="Excepciones..." name="RenderExceptionsButton"/>
- <button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/>
- <button label="Cargar predefinido..." name="PrefLoadButton"/>
+ <button label="Guardar configuración como valor predefinido" name="PrefSaveButton" width="260" left="5"/>
+ <button label="Cargar predefinido" name="PrefLoadButton" left_pad="7"/>
min_val=&quot;0.125&quot;
- <button label="Eliminar predefinido..." name="PrefDeleteButton"/>
- <button label="Restablecer la configuración recomendada" name="Defaults"/>
+ <button label="Eliminar predefinido" name="PrefDeleteButton" width="117" left_pad="7"/>
+ <button label="Restablecer la configuración recomendada" name="Defaults" width="248"/>
<button label="Configuración avanzada..." name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
index 1b191d3e46..36888850c4 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
@@ -30,7 +30,7 @@
<combo_box.item label="Preguntarme cuando una actualización opcional está disponible para instalar" name="Install_ask"/>
<combo_box.item label="Instalar sólo actualizaciones obligatorias" name="Install_manual"/>
</combo_box>
- <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test"/>
+ <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test" left_delta="-20"/>
<check_box label="Mostrar las notas de la versión después de la actualización" name="update_show_release_notes"/>
<text name="Proxy Settings:">
Configuración de proxy:
diff --git a/indra/newview/skins/default/xui/es/panel_region_environment.xml b/indra/newview/skins/default/xui/es/panel_region_environment.xml
index a73f1deed4..3aa7e12089 100644
--- a/indra/newview/skins/default/xui/es/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Entorno" name="panel_env_info">
- <text name="water_settings_title">
- Selecciona la configuración de agua y cielo/ciclo del día que deseas que vean todos los visitantes de tu región. Más información
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Usar los valores predeterminados de Second Life" name="use_sl_default_settings"/>
- <radio_item label="Usar la configuración siguiente" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Configuración de agua
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Selecciona un valor predefinido-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Cielo/Ciclo del día
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Cielo invariable" name="my_sky_settings"/>
- <radio_item label="Ciclo del día" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Selecciona un valor predefinido-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Selecciona un valor predefinido-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Aplicar" name="apply_btn"/>
- <button label="Cancelar" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Usar la configuración predeterminada
+ </string>
+ <string name="str_label_use_region">
+ Usar Configuración de la Región
+ </string>
+ <string name="str_altitude_desription">
+ Cielo [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ No se ha seleccionado ninguna parcela. Las opciones de entorno están desactivadas.
+ </string>
+ <string name="str_cross_region">
+ Las opciones de entorno no están disponibles en las fronteras de regiones.
+ </string>
+ <string name="str_legacy">
+ La configuración de entorno no está disponible en esta región.
+ </string>
+ <string name="str_disallowed">
+ El administrador del estado no permite cambiar los entornos de parcela en esta región.
+ </string>
+ <string name="str_too_small">
+ La parcela debe tener como mínimo 128 metros cuadrados para ser compatible con un entorno.
+ </string>
+ <string name="str_empty">
+ (vacío)
+ </string>
+ <string name="str_region_env">
+ (entorno de la región)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Usar Inventario" name="btn_select_inventory"/>
+ <button label="Personalizar" name="btn_edit"/>
+ <check_box label="Los propietarios de parcelas pueden borrar el entorno" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Desconocido
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Mover un parámetro desde el Inventario hasta este recuadro para seleccionarlo como cielo actual."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Desconocido
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Mover un parámetro desde el Inventario hasta este recuadro para seleccionarlo como cielo actual."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Desconocido
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Mover un parámetro desde el Inventario hasta este recuadro para seleccionarlo como cielo actual."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Terreno
+ </text>
+ <line_editor name="edt_invname_ground">
+ Desconocido
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Mover un parámetro desde el Inventario hasta este recuadro para seleccionarlo como cielo a nivel del terreno."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Agua
+ </text>
+ <line_editor name="edt_invname_water">
+ Desconocido
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Mover un parámetro desde el Inventario hasta este recuadro para seleccionarlo como agua actual."/>
+ </panel>
+ <button label="Restablecer" name="btn_rst_altitudes" tool_tip="Restablecer altitudes predeterminadas"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_region_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml
index b3ee34bbfd..4cfbffb887 100644
--- a/indra/newview/skins/default/xui/es/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_estate.xml
@@ -26,17 +26,17 @@
<check_box label="Permitir el teleporte a cualquier punto" name="allow_direct_teleport"/>
<button label="Aplicar" name="apply_btn"/>
<text name="estate_manager_label">
- Administradores del estado:
+ Administradores de estado:
</text>
<text name="allow_resident_label">
- Siempre permitido:
+ Siempre autorizado:
</text>
<button label="Añadir..." name="add_estate_manager_btn"/>
<button label="Quitar..." name="remove_estate_manager_btn"/>
<button label="Añadir..." name="add_allowed_avatar_btn"/>
<button label="Quitar..." name="remove_allowed_avatar_btn"/>
<text name="allow_group_label">
- Grupos siempre permitidos:
+ Grupos siempre autorizados:
</text>
<text name="ban_resident_label">
Siempre prohibido:
diff --git a/indra/newview/skins/default/xui/es/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/es/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..bce312dc18
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmósfera e Iluminación" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/es/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/es/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..0aa6f1e41a
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Nubes" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/es/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..743f901c7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Densidad" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Período exponencial Rayleigh:" name="rayleigh_exponential"/>
+ <slider label="Escala exponencial Rayleigh:" name="rayleigh_exponential_scale"/>
+ <slider label="Período lineal Rayleigh:" name="rayleigh_linear"/>
+ <slider label="Período constante Rayleigh:" name="rayleigh_constant"/>
+ <slider label="Altitud máxima Rayleigh:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Período exponencial Mie:" name="mie_exponential"/>
+ <slider label="Escala exponencial Mie:" name="mie_exponential_scale"/>
+ <slider label="Período lineal Mie:" name="mie_linear"/>
+ <slider label="Período constante Mie:" name="mie_constant"/>
+ <slider label="Factor Aniso Mie:" name="mie_aniso_factor"/>
+ <slider label="Altitud máxima Mie:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Período exponencial de Absorción:" name="absorption_exponential"/>
+ <slider label="Escala exponencial de Absorción:" name="absorption_exponential_scale"/>
+ <slider label="Período lineal de Absorción:" name="absorption_linear"/>
+ <slider label="Período constante de Absorción:" name="absorption_constant"/>
+ <slider label="Altitud máxima de Absorción:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/es/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..77db745755
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Sol y Luna" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Mostrar baliza" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Mostrar baliza" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_settings_water.xml b/indra/newview/skins/default/xui/es/panel_settings_water.xml
new file mode 100644
index 0000000000..c0d0cb5636
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Agua" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Compensación Fresnel:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_tools_texture.xml b/indra/newview/skins/default/xui/es/panel_tools_texture.xml
index 6ab95b9f5d..fb1aa50198 100644
--- a/indra/newview/skins/default/xui/es/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/es/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Textura" name="Texture">
- <panel.string name="string repeats per meter">
- Repeticiones por metro
- </panel.string>
- <panel.string name="string repeats per face">
- Repeticiones por cara
- </panel.string>
<text name="color label">
Color
</text>
@@ -114,4 +108,5 @@
<spinner label="Desplazamiento horizontal" name="shinyOffsetU"/>
<spinner label="Desplazamiento vertical" name="shinyOffsetV"/>
<check_box initial_value="false" label="Alinear caras del plano" name="checkbox planar align" tool_tip="Alinear texturas en todas las caras seleccionadas con la última cara seleccionada. Requiere la representación de texturas en el plano."/>
+ <button label="Centrar" label_selected="Alinear capas de textura actuales" name="button align textures" tool_tip="Alinear capas de textura actuales"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/role_actions.xml b/indra/newview/skins/default/xui/es/role_actions.xml
index 80379da064..cfa37432a8 100644
--- a/indra/newview/skins/default/xui/es/role_actions.xml
+++ b/indra/newview/skins/default/xui/es/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Cambiar música y configuraciones de los media" longdescription="Cambiar la música en streaming y las configuraciones de vídeo en Acerca del terreno &gt; pestaña Media." name="land change media" value="20"/>
<action description="Activar/desactivar &apos;Editar el terreno&apos;" longdescription="Activar/desactivar &apos;Editar el terreno&apos;. *AVISO* Acerca del terreno &gt; pestaña Opciones &gt; Editar el terreno, permite a cualquiera alterar la forma de su terreno y sustituir y mover plantas Linden. Asegúrese de lo que está haciendo antes de otorgar esta capacidad. La edición del terreno se activada/desactiva en Acerca del terreno &gt; pestaña Opciones." name="land edit" value="21"/>
<action description="Activar/desactivar varios ítems de Acerca del terreno &gt; Opciones" longdescription="Cambia &apos;Seguro (sin daño)&apos;, &apos;Volar&apos;, y el permitir a otros residentes en terrenos propiedad del grupo &apos;Modificar el terreno&apos;, &apos;Construir&apos;, &apos;Crear hitos&apos; y &apos;Ejecutat scripts&apos;, como aparece en Acerca del terreno &gt; pestaña Opciones." name="land options" value="22"/>
+ <action description="Modificar configuración del entorno y ciclo del día" longdescription="Cambiar la configuración de entorno y el ciclo del día desde la pestaña Acerca del terreno &gt; Entorno" name="land change environment" value="46"/>
</action_set>
<action_set description="Estas capacidades incluyen poderes que permiten a los miembros rebasar las restricciones de parcelas pertenecientes al grupo." name="Parcel Powers">
<action description="Permitir siempre &apos;Editar el terreno&apos;" longdescription="Quien tenga un rol con esta capacidad puede editar el terreno de una parcela perteneciente al grupo aunque eso esté desactivado en Acerca del terreno &gt; pestaña Opciones." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index c9bfbd6610..f5e7d0bf4e 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -630,6 +630,15 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="BUTTON_HELP">
Ver la Ayuda
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Los objetos de este tipo no se pueden adjuntar
+a las notas de esta región.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Sólo los objetos con permisos
+«próximo propietario» sin restricciones
+pueden adjuntarse a las notas.
+ </string>
<string name="Searching">
Buscando...
</string>
@@ -706,6 +715,18 @@ Intenta iniciar sesión de nuevo en unos instantes.
Error en la solicitud de carga. Por favor, ingresa a
http://secondlife.com/support para obtener ayuda sobre cómo solucionar este problema.
</string>
+ <string name="SettingValidationError">
+ Error en la validación para importar los parámetros [NAME]
+ </string>
+ <string name="SettingImportFileError">
+ No se pudo abrir el archivo [FILE]
+ </string>
+ <string name="SettingParseFileError">
+ No se pudo abrir el archivo [FILE]
+ </string>
+ <string name="SettingTranslateError">
+ No se pudo traducir el Viento de luz legado [NAME]
+ </string>
<string name="texture">
la textura
</string>
@@ -781,6 +802,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="symbolic folder link">
enlace de la carpeta
</string>
+ <string name="settings blob">
+ opciones
+ </string>
<string name="mesh">
red
</string>
@@ -1108,6 +1132,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="ForceSitAvatar">
Forzar que el avatar se siente
</string>
+ <string name="ChangeEnvSettings">
+ Cambiar tu configuración del entorno
+ </string>
<string name="AgentNameSubst">
(Tú)
</string>
@@ -1256,6 +1283,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="tattoo">
Tatuaje
</string>
+ <string name="universal">
+ Universal
+ </string>
<string name="physics">
Física
</string>
@@ -1298,6 +1328,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="tattoo_not_worn">
Tatuaje no puesto
</string>
+ <string name="universal_not_worn">
+ Universal no puesto
+ </string>
<string name="physics_not_worn">
Física no puesta
</string>
@@ -1349,6 +1382,9 @@ http://secondlife.com/support para obtener ayuda sobre cómo solucionar este pro
<string name="create_new_tattoo">
Crear un tatuaje nuevo
</string>
+ <string name="create_new_universal">
+ Crear unos guantes nuevos
+ </string>
<string name="create_new_physics">
Crear nueva física
</string>
@@ -1592,11 +1628,14 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="MarketplaceUpdating">
actualizando...
</string>
+ <string name="UploadFeeInfo">
+ Las tasas se basan en tu nivel de suscripción. Niveles más altos tienen tasas más bajas. [https://secondlife.com/my/account/membership.php? Aprende más al respecto]
+ </string>
<string name="Open landmarks">
- Abrir hitos
+ Abrir puntos destacados
</string>
<string name="Unconstrained">
- Sin restricciones
+ Sin Restricciones
</string>
<string name="no_transfer" value="(no transferible)"/>
<string name="no_modify" value="(no modificable)"/>
@@ -2484,6 +2523,27 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="RegionSettings">
Configuración de la región
</string>
+ <string name="NoEnvironmentSettings">
+ Esta región no es compatible con las opciones de entorno.
+ </string>
+ <string name="EnvironmentSun">
+ Sol
+ </string>
+ <string name="EnvironmentMoon">
+ Luna
+ </string>
+ <string name="EnvironmentBloom">
+ Florecimiento
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Ruido de nubes
+ </string>
+ <string name="EnvironmentNormalMap">
+ Vista Normal
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparente
+ </string>
<string name="ClassifiedClicksTxt">
Clics: [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil
</string>
@@ -4640,6 +4700,9 @@ Denuncia de infracción
<string name="New Tattoo">
Tatuaje nuevo
</string>
+ <string name="New Universal">
+ Nuevo Universal
+ </string>
<string name="New Physics">
Nueva física
</string>
@@ -4766,6 +4829,15 @@ Denuncia de infracción
<string name="Female - Wow">
Mujer - Admiración
</string>
+ <string name="New Daycycle">
+ Nuevo Ciclo del día
+ </string>
+ <string name="New Water">
+ Nueva Agua
+ </string>
+ <string name="New Sky">
+ Nuevo Cielo
+ </string>
<string name="/bow">
/reverencia
</string>
@@ -5294,6 +5366,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="BeaconMedia">
Viendo balizas de medios (blancas)
</string>
+ <string name="BeaconSun">
+ Visualización de la baliza de dirección del sol (naranja)
+ </string>
+ <string name="BeaconMoon">
+ Visualización de la baliza de dirección de la luna (violeta)
+ </string>
<string name="ParticleHiding">
Ocultando las partículas
</string>
@@ -5321,6 +5399,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Command_Destinations_Label">
Destinos
</string>
+ <string name="Command_Environments_Label">
+ Mis entornos
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5414,6 +5498,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Command_Destinations_Tooltip">
Destinos de interés
</string>
+ <string name="Command_Environments_Tooltip">
+ Mis entornos
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Publicar en Facebook
+ </string>
<string name="Command_Flickr_Tooltip">
Subir a Flickr
</string>
@@ -5609,6 +5699,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="ExperiencePermission12">
aceptar automáticamente permisos de experiencias
</string>
+ <string name="ExperiencePermission16">
+ forzar que el avatar se siente
+ </string>
+ <string name="ExperiencePermission17">
+ cambiar tu configuración del entorno
+ </string>
<string name="ExperiencePermissionShortUnknown">
realizar una operación desconocida: [Permission]
</string>
@@ -5633,6 +5729,12 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="ExperiencePermissionShort12">
Otorgar permisos
</string>
+ <string name="ExperiencePermissionShort16">
+ Sentarte
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Entorno
+ </string>
<string name="logging_calls_disabled_log_empty">
No se están registrando las conversaciones. Para empezar a grabar un registro, elige &quot;Guardar: Solo registro&quot; o &quot;Guardar: Registro y transcripciones&quot; en Preferencias &gt; Chat.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index 219857eb99..fe863fc565 100644
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -366,10 +366,10 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
Photo :
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Les avatars sur d&apos;autres parcelles peuvent voir et chatter avec les avatars sur cette parcelle.
</text>
- <check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
+ <check_box label="Voir les avatars" name="SeeAvatarsCheck" top="170" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
<text name="landing_point">
Lieu d&apos;arrivée : [LANDING]
</text>
@@ -449,7 +449,7 @@ musique :
<panel.string name="estate_override">
Au moins une de ces options est définie au niveau du domaine.
</panel.string>
- <check_box label="Tout le monde peut rendre visite (Des lignes d&apos;interdiction seront créées si cette case n&apos;est pas cochée)" name="public_access"/>
+ <check_box label="Tout le monde peut rendre visite" tool_tip="Des lignes d&apos;interdiction seront créées si cette case n&apos;est pas cochée" name="public_access"/>
<check_box label="Doit avoir plus de 18 ans [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour accéder à cette parcelle, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Les infos de paiement doivent être enregistrées dans le dossier [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Pour pouvoir accéder à cette parcelle, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Autoriser le groupe [GROUP] sans restrictions" name="GroupCheck" tool_tip="Définir le groupe à l&apos;onglet Général."/>
@@ -484,5 +484,6 @@ musique :
</panel>
</panel>
<panel label="EXPÉRIENCES" name="land_experiences_panel"/>
+ <panel label="ENVIRONNEMENT" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_adjust_environment.xml b/indra/newview/skins/default/xui/fr/floater_adjust_environment.xml
new file mode 100644
index 0000000000..ca5b0ec948
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Éclairage personnel">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Réinitialiser" name="btn_reset" tool_tip="Fermer et réinitialiser vers l&apos;environnement partagé"/>
+ <text name="cloud_map_label">
+ Image du nuage :
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Soleil :
+ </text>
+ <check_box label="Afficher la balise" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Afficher la balise" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_beacons.xml b/indra/newview/skins/default/xui/fr/floater_beacons.xml
index ebd4dab683..c6adf67bac 100644
--- a/indra/newview/skins/default/xui/fr/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/fr/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Sources sonores" name="sounds"/>
<check_box label="Sources des particules" name="particles"/>
<check_box label="Sources des médias" name="moapbeacon"/>
+ <check_box label="Soleil" name="sun"/>
+ <check_box label="Lune" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
index 02b58f9b36..09186b6777 100644
--- a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="Sons"/>
<check_box label="Textures" name="check_texture"/>
<icon name="icon_texture" tool_tip="Textures"/>
+ <icon name="icon_setting" tool_tip="Paramètres d&apos;environnement"/>
<button label="√ Tout" label_selected="Tout" name="check_all"/>
<button label="Effacer" label_selected="Aucun" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 148a5a35d2..55b0d1825a 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -60,8 +60,7 @@ le Lindex...
</text>
<button label="Acheter" name="buy_btn"/>
<button label="Annuler" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5" width="200">
+ <floater.string name="info_cannot_buy" left="160" width="200">
Achat impossible
- </text>
- <button label="Accéder au Web" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml
deleted file mode 100644
index c666a25c10..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="SUPPRIMER PRÉRÉGLAGE ENV.">
- <string name="title_water">
- Supprimer un préréglage de l&apos;eau
- </string>
- <string name="title_sky">
- Supprimer un préréglage du ciel
- </string>
- <string name="title_day_cycle">
- Supprimer un cycle du jour
- </string>
- <string name="label_water">
- Préréglage :
- </string>
- <string name="label_sky">
- Préréglage :
- </string>
- <string name="label_day_cycle">
- Cycle du jour :
- </string>
- <string name="msg_confirm_deletion">
- Voulez-vous vraiment supprimer le préréglage sélectionné ?
- </string>
- <string name="msg_sky_is_referenced">
- Impossible de supprimer un préréglage référencé dans un ou plusieurs cycles du jour.
- </string>
- <string name="combo_label">
- -Sélectionner un préréglage-
- </string>
- <text name="label">
- Préréglage :
- </text>
- <button label="Supprimer" name="delete"/>
- <button label="Annuler" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/fr/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..7e8e76fd5a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Modifier un cycle du jour">
+ <string name="title_new">
+ Créer un nouveau cycle du jour
+ </string>
+ <string name="title_edit">
+ Modifier un cycle du jour
+ </string>
+ <string name="hint_new">
+ Donner un nom au cycle du jour, ajuster les contrôles afin de le créer, puis cliquez sur « Enregistrer ».
+ </string>
+ <string name="hint_edit">
+ Pour modifier le cycle du jour, ajustez les contrôles ci-dessous, puis cliquez sur « Enregistrer ».
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Ciel [ALT]
+ </string>
+ <string name="sky_label">
+ Ciel
+ </string>
+ <string name="water_label">
+ Eau
+ </string>
+ <string name="commit_parcel">
+ Appliquer à la parcelle
+ </string>
+ <string name="commit_region">
+ Appliquer à la région
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Nom du cycle du jour :
+ </text>
+ <button label="Importer" name="btn_import" tool_tip="Importer les paramètres hérités du disque."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Ciel 4" name="sky4_track"/>
+ <button label="Ciel 3" name="sky3_track"/>
+ <button label="Ciel 2" name="sky2_track"/>
+ <button label="Niveau du sol" name="sky1_track"/>
+ <button label="Eau" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Cloner la piste à partir" name="copy_track"/>
+ <button label="Charger la piste à partir" name="load_track"/>
+ <button label="Effacer la piste" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Reculer"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Avancer"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="Ajouter [FRAME]" name="add_frame"/>
+ <button label="Charger [FRAME]" name="btn_load_frame"/>
+ <button label="Annuler [FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Sélectionnez un cadre clé à partir du calendrier ci-dessus pour modifier les paramètres.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Eau" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmosphère et éclairage" name="atmosphere_panel"/>
+ <panel label="Nuages" name="clouds_panel"/>
+ <panel label="Soleil et lune" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Enregistrer" name="save_btn"/>
+ <button label="Annuler" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/fr/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..515a1d2843
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Environnement fixe">
+ <string name="edit_sky">
+ Modifier le ciel :
+ </string>
+ <string name="edit_water">
+ Modifier l&apos;eau
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Charger" name="btn_load" tool_tip="Charger des paramètres à partir de l&apos;inventaire"/>
+ <button label="Importer" name="btn_import" tool_tip="Importer les paramètres hérités du disque."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Enregistrer" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Annuler" name="btn_cancel" tool_tip="Rétablir la dernière version enregistrée"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
index 471dddf448..4e20431cc4 100644
--- a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
@@ -12,6 +12,7 @@
<check_box label="Sons" name="check_sound"/>
<check_box label="Textures" name="check_texture"/>
<check_box label="Photos" name="check_snapshot"/>
+ <check_box label="Paramètres" name="check_settings"/>
<button label="Tout" label_selected="Tout" name="All"/>
<button bottom_delta="0" label="Aucun" label_selected="Aucun" name="None"/>
<check_box label="Toujours montrer les dossiers" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
deleted file mode 100644
index 0f657e9e5b..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="BOÃŽTE D&apos;ENVOI VENDEUR">
- <string name="OutboxFolderCount1">
- 1 dossier
- </string>
- <string name="OutboxFolderCountN">
- [NUM] dossiers
- </string>
- <string name="OutboxImporting">
- Envoi de dossiers...
- </string>
- <string name="OutboxInitializing">
- Initialisation...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Chargement...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Faites glisser des éléments ici pour créer des dossiers
- </text>
- </panel>
- <button label="Envoyer vers la Place du marché" name="outbox_import_btn" tool_tip="Vers ma vitrine de la Place du marché"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_my_environments.xml b/indra/newview/skins/default/xui/fr/floater_my_environments.xml
new file mode 100644
index 0000000000..5ee6e2d5fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Endroits" name="my_environments" title="MES ENVIRONNEMENTS">
+ <layout_stack>
+ <layout_panel label="Filtres" name="filter_panel">
+ <check_box label="Jours" name="chk_days"/>
+ <check_box label="Ciels" name="chk_skies"/>
+ <check_box label="Eau" name="chk_water"/>
+ <filter_editor label="Filtrer les environnements" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Environnements" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Afficher tous les dossiers" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Plus d&apos;options"/>
+ <menu_button name="btn_newsettings" tool_tip="Créer un nouveau paramètre"/>
+ <button name="btn_del" tool_tip="Supprimer l&apos;article sélectionné"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_perms_default.xml b/indra/newview/skins/default/xui/fr/floater_perms_default.xml
index 1cea8e55cc..ef56ce5663 100644
--- a/indra/newview/skins/default/xui/fr/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/fr/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Définir les droits par défaut pour la création d’habits ou de parties de corps">
Articles à porter
</text>
+ <text name="label_13" tool_tip="Définir les autorisations par défaut pour la création des paramètres environnementaux">
+ Paramètres
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Annuler" label_selected="Annuler" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_pick_track.xml b/indra/newview/skins/default/xui/fr/floater_pick_track.xml
new file mode 100644
index 0000000000..46731bcec7
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="CHOISIR : PISTE">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Sélectionner la source du ciel :
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Ciel4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Ciel3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Ciel2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Sol" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Annuler" label_selected="Annuler" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml
index fd47254934..42af9c526d 100644
--- a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Eau transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Placage de relief et brillance" name="BumpShiny"/>
<check_box initial_value="true" label="Lumières locales" name="LocalLights"/>
- <check_box initial_value="true" label="Effets de base" name="BasicShaders" tool_tip="La désactivation de cette option peut éviter le plantage de certains pilotes de cartes graphiques"/>
<slider label="Rendu du terrain :" name="TerrainDetail"/>
<text name="TerrainDetailText">
Faible
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 9fc9d14026..d63d9903ec 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
@@ -10,12 +10,12 @@
Description :
</text>
<text name="dimensions">
- [WIDTH] px x [HEIGHT] px
+ [WIDTH]px x [HEIGHT]px
</text>
<text name="aspect_ratio">
- Aperçu du rapport hauteur/largeur
+ Rapport d&apos;aspect fixe
</text>
- <combo_box name="combo_aspect_ratio" tool_tip="Aperçu avec un rapport hauteur/largeur fixe">
+ <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>
diff --git a/indra/newview/skins/default/xui/fr/floater_settings_picker.xml b/indra/newview/skins/default/xui/fr/floater_settings_picker.xml
new file mode 100644
index 0000000000..b75d8c6b8d
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="CHOISIR : PARAMÈTRES">
+ <floater.string name="pick title">
+ Choisir :
+ </floater.string>
+ <floater.string name="pick_track">
+ SÉLECTIONNER UNE PISTE
+ </floater.string>
+ <floater.string name="pick_settings">
+ SÉLECTIONNEZ LES PARAMÈTRES
+ </floater.string>
+ <floater.string name="track_water">
+ Eau
+ </floater.string>
+ <floater.string name="track_ground">
+ Sol
+ </floater.string>
+ <floater.string name="track_sky">
+ Ciel[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Filtrer les textures" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Annuler" label_selected="Annuler" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
index eace67026c..a4de7954c5 100644
--- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
@@ -9,18 +9,14 @@
<text name="Multiple">
Textures multiples
</text>
- <radio_group name="mode_selection">
- <radio_item label="Inventaire" name="inventory" value="0"/>
- <radio_item label="Local" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Taille : [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Inventaire" name="inventory" value="0"/>
+ <combo_box.item label="Local" name="local" value="1"/>
+ </combo_box>
<button label="Défaut" label_selected="Défaut" name="Default" width="60"/>
<button label="Vierge" label_selected="Vierge" name="Blank" width="60"/>
<button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/>
<button bottom="-240" label="" label_selected="" name="Pipette"/>
- <check_box initial_value="true" label="Appliquer maintenant" name="apply_immediate_check"/>
<text name="preview_disabled" value="Aperçu désactivé"/>
<filter_editor label="Filtrer les textures" name="inventory search editor"/>
<check_box initial_value="false" label="Afficher les dossiers" name="show_folders_check"/>
@@ -31,6 +27,22 @@
<column label="Nom" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Choisir la texture mixte">
+ <combo_box.item label="Aucun" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Masquer la région maillée de base" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="Annuler" label_selected="Annuler" name="Cancel"/>
+ <check_box initial_value="true" label="Appliquer maintenant" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
index a4ead48b6b..32bc564d72 100644
--- a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Toucher" name="touch_attach" />
+ <menu_item_call label="Modifier" name="edit_item" />
<menu_item_call label="Détacher" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml
index c8bd7dc130..5d66d0998b 100644
--- a/indra/newview/skins/default/xui/fr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Activer" name="Marketplace Activate"/>
<menu_item_call label="Désactiver" name="Marketplace Deactivate"/>
<menu_item_call label="Partager" name="Share"/>
- <menu_item_call label="Acheter" name="Task Buy"/>
<menu_item_call label="Ouvrir" name="Task Open"/>
<menu_item_call label="Jouer" name="Task Play"/>
<menu_item_call label="Propriétés" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Nouveau caleçon" name="New Underpants"/>
<menu_item_call label="Nouveau masque alpha" name="New Alpha Mask"/>
<menu_item_call label="Nouveau tatouage" name="New Tattoo"/>
+ <menu_item_call label="Nouvel environnement universel" name="New Universal"/>
<menu_item_call label="Nouvelles propriétés physiques" name="New Physics"/>
</menu>
<menu label="Nouvelles parties du corps" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Nouveaux cheveux" name="New Hair"/>
<menu_item_call label="Nouveaux yeux" name="New Eyes"/>
</menu>
+ <menu label="Nouveaux paramètres" name="New Settings">
+ <menu_item_call label="Nouveau ciel" name="New Sky"/>
+ <menu_item_call label="Nouvelle eau" name="New Water"/>
+ <menu_item_call label="Nouveau cycle du jour" name="New Day Cycle"/>
+ </menu>
<menu label="Utiliser comme défaut pour" name="upload_def">
<menu_item_call label="Chargements d’images" name="Image uploads"/>
<menu_item_call label="Chargements de sons" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Porter" name="Wearable And Object Wear"/>
<menu label="Attacher à" name="Attach To"/>
<menu label="Attacher au HUD " name="Attach To HUD"/>
+ <menu_item_call label="Toucher" name="Attachment Touch" />
<menu_item_call label="Modifier" name="Wearable Edit"/>
<menu_item_call label="Ajouter" name="Wearable Add"/>
<menu_item_call label="Enlever" name="Take Off"/>
+ <menu_item_call label="Appliquer uniquement à moi-même" name="Settings Apply Local"/>
+ <menu_item_call label="Appliquer à la parcelle" name="Settings Apply Parcel"/>
<menu_item_call label="Copier dans les annonces Place du marché" name="Marketplace Copy"/>
<menu_item_call label="Déplacer dans les annonces Place du marché" name="Marketplace Move"/>
<menu_item_call label="--aucune option--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory_add.xml b/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
index 1076af44d9..de510eaeaa 100644
--- a/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Son ([COST] L$)..." name="Upload Sound"/>
<menu_item_call label="Animation ([COST] L$)..." name="Upload Animation"/>
<menu_item_call label="Modèle..." name="Upload Model"/>
- <menu_item_call label="Assistant Modèle..." name="Upload Model Wizard"/>
<menu_item_call label="Lot ([COST] L$ par fichier)..." name="Bulk Upload"/>
- <menu_item_call label="Définir les droits de chargement par défaut" name="perm prefs"/>
</menu>
<menu_item_call label="Nouveau dossier" name="New Folder"/>
<menu_item_call label="Nouveau script" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Nouveau caleçon" name="New Underpants"/>
<menu_item_call label="Nouvel alpha" name="New Alpha"/>
<menu_item_call label="Nouveau tatouage" name="New Tattoo"/>
+ <menu_item_call label="Nouvel environnement universel" name="New Universal"/>
<menu_item_call label="Nouvelles propriétés physiques" name="New Physics"/>
</menu>
<menu label="Nouvelles parties du corps" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Nouveaux cheveux" name="New Hair"/>
<menu_item_call label="Nouveaux yeux" name="New Eyes"/>
</menu>
+ <menu label="Nouveaux paramètres" name="New Settings">
+ <menu_item_call label="Nouveau ciel" name="New Sky"/>
+ <menu_item_call label="Nouvelle eau" name="New Water"/>
+ <menu_item_call label="Nouveau cycle du jour" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
index 28ae2f74ad..3fce2e9f33 100644
--- a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Nouvel alpha" name="New Alpha"/>
<menu_item_call label="Nouvelles propriétés physiques" name="New Physics"/>
<menu_item_call label="Nouveau tatouage" name="New Tattoo"/>
+ <menu_item_call label="Nouvel environnement universel" name="New Universal"/>
</menu>
<menu label="Nouvelles parties du corps" name="New Body Parts">
<menu_item_call label="Nouvelle silhouette" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_save_settings.xml b/indra/newview/skins/default/xui/fr/menu_save_settings.xml
new file mode 100644
index 0000000000..34a3f00925
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Enregistrer" name="save_settings"/>
+ <menu_item_check label="Enregistrer sous" name="save_as_new_settings"/>
+ <menu_item_check label="Valider" name="commit_changes"/>
+ <menu_item_check label="Appliquer uniquement à moi-même" name="apply_local"/>
+ <menu_item_check label="Appliquer à la parcelle" name="apply_parcel"/>
+ <menu_item_check label="Appliquer à la région" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_settings_add.xml b/indra/newview/skins/default/xui/fr/menu_settings_add.xml
new file mode 100644
index 0000000000..cbd7cba494
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Nouveau ciel" name="New Sky"/>
+ <menu_item_call label="Nouvelle eau" name="New Water"/>
+ <menu_item_call label="Nouveau cycle du jour" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_settings_gear.xml b/indra/newview/skins/default/xui/fr/menu_settings_gear.xml
new file mode 100644
index 0000000000..a4e52d373b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Modifier" name="edit_settings"/>
+ <menu_item_call label="Appliquer uniquement à moi-même" name="Settings Apply Local"/>
+ <menu_item_call label="Appliquer à la parcelle" name="Settings Apply Parcel"/>
+ <menu_item_call label="Appliquer à la région" name="Settings Apply Region"/>
+ <menu_item_call label="Copier" name="copy_settings"/>
+ <menu_item_call label="Coller" name="paste_settings"/>
+ <menu_item_call label="Copier l’UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 12c50464da..2594e9d0bb 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="Propriétés de la parcelle" name="Parcel Properties"/>
<menu_item_check label="Menu Avancé" name="Show Advanced Menu"/>
</menu>
- <menu label="Soleil" name="Sun">
+ <menu label="Environnement" name="Environment">
<menu_item_check label="Aube" name="Sunrise"/>
<menu_item_check label="Midi" name="Noon"/>
<menu_item_check label="Coucher de soleil" name="Sunset"/>
<menu_item_check label="Minuit" name="Midnight"/>
- <menu_item_check label="Utiliser les réglages de la région" name="Use Region Settings"/>
- </menu>
- <menu label="Éditeur d&apos;environnement" name="Environment Editor">
- <menu_item_call label="Paramètres d&apos;environnement..." name="Environment Settings"/>
- <menu label="Préréglages de l&apos;eau" name="Water Presets">
- <menu_item_call label="Nouveau préréglage..." name="new_water_preset"/>
- <menu_item_call label="Modifier un préréglage..." name="edit_water_preset"/>
- <menu_item_call label="Supprimer un préréglage..." name="delete_water_preset"/>
- </menu>
- <menu label="Préréglages du ciel" name="Sky Presets">
- <menu_item_call label="Nouveau préréglage..." name="new_sky_preset"/>
- <menu_item_call label="Modifier un préréglage..." name="edit_sky_preset"/>
- <menu_item_call label="Supprimer un préréglage..." name="delete_sky_preset"/>
- </menu>
- <menu label="Préréglages du jour" name="Day Presets">
- <menu_item_call label="Nouveau préréglage..." name="new_day_preset"/>
- <menu_item_call label="Modifier un préréglage..." name="edit_day_preset"/>
- <menu_item_call label="Supprimer un préréglage..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Utiliser l&apos;environnement partagé" name="Use Shared Environment"/>
+ <menu_item_call label="Mes environnements..." name="my_environs"/>
+ <menu_item_call label="Éclairage personnel..." name="adjustment_tool"/>
+ <menu_item_check label="Pause des nuages" name="pause_clouds"/>
</menu>
</menu>
<menu label="Construire" name="BuildTools">
@@ -346,6 +331,9 @@
<menu_item_check label="Masques alpha automatiques (non différés)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Textures d&apos;animation" name="Animation Textures"/>
<menu_item_check label="Désactiver les textures" name="Disable Textures"/>
+ <menu_item_check label="Désactiver l&apos;ambiance" name="Disable Ambient"/>
+ <menu_item_check label="Désactiver la lumière du soleil" name="Disable Sunlight"/>
+ <menu_item_check label="Désactiver les lumières locales" name="Disable Local Lights"/>
<menu_item_check label="Textures pleine résolution" name="Rull Res Textures"/>
<menu_item_check label="Rendu des lumières jointes" name="Render Attached Lights"/>
<menu_item_check label="Rendu des particules jointes" name="Render Attached Particles"/>
@@ -483,6 +471,7 @@
<menu_item_call label="Jupe" name="Skirt"/>
<menu_item_call label="Alpha" name="Alpha"/>
<menu_item_call label="Tatouage" name="Tattoo"/>
+ <menu_item_call label="Universel" name="Universal"/>
<menu_item_call label="Propriétés physiques" name="Physics"/>
<menu_item_call label="Tous les habits" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
index 187cb4bcd2..a222de298f 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Remplacer" name="wear_replace"/>
<menu_item_call label="Porter" name="wear_wear"/>
<menu_item_call label="Ajouter" name="wear_add"/>
+ <menu_item_call label="Toucher" name="touch" />
<menu_item_call label="Enlever / Détacher" name="take_off_or_detach"/>
<menu_item_call label="Détacher" name="detach"/>
<context_menu label="Attacher à" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
index c3d9d908b0..90b5ece574 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Modifier la tenue" name="edit"/>
+ <menu_item_call label="Toucher" name="touch"/>
+ <menu_item_call label="Modifier" name="edit_item"/>
+ <menu_item_call label="Modifier la tenue" name="edit_outfit"/>
<menu_item_call label="Enlever" name="takeoff"/>
<menu_item_call label="Copier la liste de la tenue dans le presse-papiers" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
index 5a7193a7cc..af115b956e 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Toucher" name="touch_attach"/>
<menu_item_call label="Enlever" name="take_off"/>
<menu_item_call label="Détacher" name="detach"/>
- <menu_item_call label="Modifier la tenue" name="edit"/>
+ <menu_item_call label="Modifier la tenue" name="edit_outfit"/>
<menu_item_call label="Modifier" name="edit_item"/>
<menu_item_call label="Afficher l’original" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 54f132f684..e84de375d8 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -266,6 +266,10 @@ Souhaitez-vous accorder des droits d&apos;édition aux résidents sélectionnés
Souhaitez-vous retirer les droits d&apos;édition aux résidents selectionnés ?
<usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ Un nom de groupe doit être compris entre [MIN_LEN] et [MAX_LEN] caractères.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
Impossible de créer le groupe.
[MESSAGE]
@@ -359,7 +363,7 @@ Souhaitez-vous continuer ?
Vous n&apos;avez pas suffisamment de L$ pour rejoindre ce groupe.
</notification>
<notification name="CreateGroupCost">
- La création de ce groupe coûte 100 L$.
+ La création de ce groupe coûtera L$[COST].
Les groupes doivent comporter plus d&apos;un membre, sinon ils sont supprimés.
Veuillez inviter des membres d&apos;ici 48 heures.
<usetemplate canceltext="Annuler" name="okcancelbuttons" notext="Annuler" yestext="Créer un groupe pour 100 L$"/>
@@ -500,6 +504,9 @@ Pour ne placer le média que sur une seule face, choisissez Sélectionner une fa
<notification name="ErrorEncodingSnapshot">
Erreur d&apos;encodage de la photo.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Vous avez besoin de L$[COST] pour charger cet élément.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Il vous faut [COST] L$ pour enregistrer une photo dans votre inventaire. Vous pouvez acheter des L$ ou enregistrer la photo sur votre ordinateur.
</notification>
@@ -1736,11 +1743,14 @@ Quitter le groupe ?
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- Le nombre de groupes maximum est [MAX_BASIC] pour les comptes basiques et
-[MAX_PREMIUM] pour les comptes [https://secondlife.com/premium/ premium].
-Si vous avez rétrogradé votre compte, vous devez réduire votre nombre de groupes pour passer sous le nombre de groupes maximum ([MAX_BASIC]) avant de pouvoir en rejoindre d’autres.
-
-[https://secondlife.com/my/account/membership.php Mettez à niveau dès aujourd’hui !]
+ Les résidents ayant une adhésion de base peuvent s'inscrire à [MAX_BASIC] groupes maximum.
+Les adhésions premium permettent jusqu'à [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? En savoir plus ou actualiser]
+ <usetemplate name="okbutton" yestext="Fermer"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ Les résidents ayant une adhésion de base peuvent s'inscrire à [MAX_BASIC] groupes maximum.
+Les adhésions premium permettent jusqu'à [MAX_PREMIUM]. Les adhésions à Premium Plus permettent
+jusqu'à [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? En savoir plus ou actualiser]
<usetemplate name="okbutton" yestext="Fermer"/>
</notification>
<notification name="KickUser">
@@ -1959,6 +1969,11 @@ Cette action modifiera des milliers de régions et sera difficile à digérer po
Le fait de décocher cette option est susceptible de lever les restrictions que les propriétaires des parcelles ont ajouté pour éviter tout différend, maintenir la confidentialité ou protéger les jeunes résidents contre tout contenu réservé aux adultes. Veuillez discuter avec les propriétaires du terrain si nécessaire.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Si vous décochez cette option, tous les environnements personnalisés que les propriétaires de parcelles ont ajoutés à leurs parcelles seront supprimés. Veuillez discuter avec les propriétaires de votre parcelle si nécessaire.
+Souhaitez-vous continuer ?
+ <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
<usetemplate name="okbutton" yestext="OK"/>
@@ -2439,7 +2454,15 @@ Liez-la à partir d&apos;une page web pour permettre aux autres résidents d&apo
Une dossier semble manquer au Cycle du jour : [SKY].
</notification>
<notification name="WLRegionApplyFail">
- Impossible d&apos;appliquer les réglages à la région. Le problème est parfois résolu en quittant la région puis en y revenant. Motif fourni : [FAIL_REASON]
+ Impossible d&apos;appliquer les réglages à la région. Raison : [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Une texture locale est utilisée sur la piste [TRACK], le cadre n° [FRAMENO] ([FRAME]%) dans le champ [FIELD].
+Les paramètres ne seront peut-être pas enregistrés en utilisant les textures locales
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Une texture locale est utilisée dans le champ [FIELD].
+Les paramètres ne seront peut-être pas enregistrés en utilisant les textures locales
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Impossible de supprimer la dernière clé de ce cycle du jour car ce dernier ne peut pas être vide. Modifiez la dernière clé restante au lieu d&apos;essayer de la supprimer puis d&apos;en créer une nouvelle.
@@ -3291,6 +3314,22 @@ Elles vont être bloquées pendant quelques secondes pour votre sécurité.
Le modérateur ignore vos paroles.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Malheureusement, nous n'avons pas pu obtenir d'informations sur les avantages pour cette session. Cela ne devrait pas se produire dans un environnement de production normal. Veuillez contacter le service d'assistance. Cette session ne fonctionnera pas normalement et nous vous recommandons de recommencer.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Ceci permettra de charger [COUNT] éléments pour un coût total de L$[COST]. Souhaitez-vous poursuivre le téléchargement ?
+ <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Charger"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Les fichiers sélectionnés ne peuvent pas être téléchargés en masse.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Certains des fichiers sélectionnés ne peuvent pas être téléchargés en masse.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
Ce chargement coûtera [PRICE] L$. Continuer ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Charger"/>
@@ -4389,4 +4428,76 @@ Veuillez sélectionner un terrain plus petit.
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ Impossible de charger les paramètres de [NOM] à partir de la base de données.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Impossible d&apos;appliquer ces paramètres à l&apos;environnement.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Impossible d&apos;appliquer ces paramètres à l&apos;environnement.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Cette région ne prend pas en charge les paramètres environnementaux.
+ </notification>
+ <notification label="Enregistrer la tenue" name="SaveSettingAs">
+ Enregistrer les paramètres environnementaux actuels sous :
+ <form name="form">
+ <input name="message">
+ [DESC] (nouv.)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Annuler"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Impossible d&apos;importer les paramètres Windlight [NAME] hérités de
+[FILE].
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Impossible de définir l&apos;environnement pour cette parcelle.
+Veuillez entrer ou sélectionner une parcelle que vous avez le droit de modifier.
+ </notification>
+ <notification name="SettingsUnsuported">
+ Les paramètres ne sont pas pris en charge dans cette région.
+Veuillez vous déplacer dans une région où les paramètres sont activés et relancer votre action.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Vous êtes sur le point de perdre les modifications que vous avez apportées à ce [TYPE] nommé &quot;[NAME]&quot;.
+Voulez-vous vraiment continuer ?
+ <usetemplate ignoretext="Voulez-vous vraiment perdre les modifications ?" name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Vous êtes sur le point de supprimer tous les paramètres appliqués.
+Voulez-vous vraiment continuer ?
+ <usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Vous êtes sur le point de supprimer tous les paramètres d&apos;éclairage personnel appliqués.
+Voulez-vous vraiment continuer ?
+ <usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Vous êtes sur le point d&apos;importer des paramètres non transférables dans ce cycle de jour. Si vous continuez, les paramètres que vous modifiez deviennent également non transférables.
+
+Cette modification ne peut être être annulée.
+
+Voulez-vous vraiment continuer ?
+ <usetemplate ignoretext="Voulez-vous vraiment que ces paramètres soient non transférables ?" name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Vous ne pouvez pas modifier les paramètres directement à partir de la bibliothèque.
+Veuillez copier vers votre inventaire puis réessayer
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Nous avons rencontré un problème avec ces paramètres. Ils ne peuvent pas être enregistres ou appliqués pour l&apos;instant.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Impossible de charger la piste dans [TRACK].
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Impossible de charger la piste de [TRACK1] dans [TRACK2].
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
index 086542dee2..24b4fc212a 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Tatouage tête" name="Head Tattoo" tool_tip="Cliquez pour sélectionner une image"/>
- <texture_picker label="Tatouage haut" name="Upper Tattoo" tool_tip="Cliquez pour sélectionner une image"/>
- <texture_picker label="Tatouage bas" name="Lower Tattoo" tool_tip="Cliquez pour sélectionner une image"/>
- <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Tatouage tête" name="Head Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage haut" name="Upper Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage bas" name="Lower Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_universal.xml b/indra/newview/skins/default/xui/fr/panel_edit_universal.xml
new file mode 100644
index 0000000000..a4626123f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Tatouage tête" name="Head Universal Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage haut" name="Upper Universal Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage bas" name="Lower Universal Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage jupe" name="Skirt Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage cheveux" name="Hair Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage yeux" name="Eyes Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage bras gauche" name="Left Arm Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Tatouage jambe gauche" name="Left Leg Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Aux1 Tattoo" name="Aux1 Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Aux2 Tattoo" name="Aux2 Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <texture_picker label="Aux3 Tattoo" name="Aux3 Tattoo" tool_tip="Cliquer pour sélectionner une image."/>
+ <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml b/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
index def158cf68..d8851bb42c 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Modification du tatouage
</string>
+ <string name="edit_universal_title">
+ Modifier l&apos;universel
+ </string>
<string name="edit_physics_title">
Modification des propriétés physiques
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Tatouage :
</string>
+ <string name="universal_desc_text">
+ Universel :
+ </string>
<string name="physics_desc_text">
Propriétés physiques :
</string>
diff --git a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
deleted file mode 100644
index d947dbceb8..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Glisser-déposer des articles ici afin de les préparer à la vente sur votre vitrine."/>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 95cd13eb94..3be6bae52a 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -18,7 +18,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<string name="no_groups_msg" value="Vous souhaitez trouver des groupes à rejoindre ? Utilisez [secondlife:///app/search/groups Rechercher]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Carte : double-clic ; Panoramique : Maj + faire glisser)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Téléportation : double-clic ; Panoramique : Maj + faire glisser)"/>
- <string name="GroupCountWithInfo" value="Vous appartenez à [COUNT] groupes, et pouvez en rejoindre [REMAINING] autres. [secondlife:/// Vous en voulez plus ?]"/>
+ <string name="GroupCountWithInfo" value="Vous appartenez à [COUNT] groupes et pouvez rejoindre [REMAINING] autres groupes. [secondlife:/// Augmentez votre limite]"/>
<tab_container name="tabs">
<panel label="PRÈS DE VOUS" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<dnd_button name="minus_btn" tool_tip="Quitter le groupe sélectionné"/>
</panel>
<text name="groupcount">
- Vous appartenez à [COUNT] groupes, et pouvez en rejoindre [REMAINING] autres.
+ Vous appartenez à [COUNT] groupes et pouvez rejoindre [REMAINING] autres groupes.
</text>
</panel>
<panel label="RÉCENT" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 422243445b..a0f2e0eba7 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Moyenne" name="Medium" value="1"/>
<item label="Grande" name="Large" value="2"/>
</combo_box>
- <check_box label="Bulles de chat" name="bubble_text_chat"/>
+ <check_box label="Bulles de chat" name="bubble_text_chat" left_delta="45"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index 7117ace7e1..46d6305290 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
</text>
<check_box initial_value="true" label="Toujours effectuer le rendu des amis" name="AlwaysRenderFriends"/>
<button label="Exceptions..." name="RenderExceptionsButton"/>
- <button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/>
- <button label="Charger un préréglage..." name="PrefLoadButton"/>
+ <button label="Enregistrer les paramètres comme préréglage" name="PrefSaveButton" width="260" />
+ <button label="Charger un préréglage" name="PrefLoadButton" width="132"/>
min_val=&quot;0,125&quot;
- <button label="Supprimer un préréglage..." name="PrefDeleteButton"/>
- <button label="Réinitialiser les paramètres recommandés" name="Defaults"/>
+ <button label="Supprimer un préréglage" name="PrefDeleteButton" width="148" top_delta="30" left_pad="-220"/>
+ <button label="Réinitialiser les paramètres recommandés" name="Defaults" width="255" top_delta="35"/>
<button label="Paramètres avancés" name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_environment.xml b/indra/newview/skins/default/xui/fr/panel_region_environment.xml
index a5be812ee5..5212c3a9ce 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Environnement" name="panel_env_info">
- <text name="water_settings_title">
- Sélectionnez les réglages d&apos;eau et de ciel/cycle du jour que vous souhaitez afficher pour tous les résidents visitant votre région. En savoir plus
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Utiliser les réglages par défaut de Second Life" name="use_sl_default_settings"/>
- <radio_item label="Utiliser les réglages suivants" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Réglage de l&apos;eau
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Sélectionner un préréglage-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Ciel / Cycle du jour
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Ciel fixe" name="my_sky_settings"/>
- <radio_item label="Cycle du jour" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Sélectionner un préréglage-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Sélectionner un préréglage-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Appliquer" name="apply_btn"/>
- <button label="Annuler" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Utiliser les réglages par défaut
+ </string>
+ <string name="str_label_use_region">
+ Utiliser les réglages de la région
+ </string>
+ <string name="str_altitude_desription">
+ Ciel [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ Aucune parcelle n&apos;est sélectionnée. Les paramètres environnementaux sont désactivés..
+ </string>
+ <string name="str_cross_region">
+ Les paramètres environnementaux ne sont pas disponibles dans les limites des régions.
+ </string>
+ <string name="str_legacy">
+ Les paramètres environnementaux ne sont pas disponibles dans cette région.
+ </string>
+ <string name="str_disallowed">
+ Le gérant du domaine n&apos;autorise pas la modification de l&apos;environnement des parcelles dans cette région.
+ </string>
+ <string name="str_too_small">
+ La parcelle doit faire au moins 128 mètres carrés pour supporter un environnement.
+ </string>
+ <string name="str_empty">
+ (vide)
+ </string>
+ <string name="str_region_env">
+ (environnement de la région)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Utiliser l&apos;inventaire" name="btn_select_inventory"/>
+ <button label="Personnaliser" name="btn_edit"/>
+ <check_box label="Les propriétaires de parcelle peuvent neutraliser l&apos;environnement" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Ciel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Inconnu
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Faites glisser un paramètre de l&apos;inventaire vers cette zone cible pour le sélectionner comme ciel actuel."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Ciel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Inconnu
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Faites glisser un paramètre de l&apos;inventaire vers cette zone cible pour le sélectionner comme ciel actuel."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Ciel [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Inconnu
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Faites glisser un paramètre de l&apos;inventaire vers cette zone cible pour le sélectionner comme ciel actuel."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Sol
+ </text>
+ <line_editor name="edt_invname_ground">
+ Inconnu
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Faites glisser un paramètre de l&apos;inventaire vers cette zone cible pour le sélectionner comme ciel au niveau du sol."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Eau
+ </text>
+ <line_editor name="edt_invname_water">
+ Inconnu
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Faites glisser un paramètre de l&apos;inventaire vers cette zone cible pour le sélectionner comme eau actuelle."/>
+ </panel>
+ <button label="Réinitialiser" name="btn_rst_altitudes" tool_tip="Rétablir les altitudes par défaut."/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/fr/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..1d6491c7e7
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmosphère et éclairage" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/fr/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..180f09653e
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Nuages" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/fr/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..107858dc20
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Densité" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Terme exponentiel de Rayleigh :" name="rayleigh_exponential"/>
+ <slider label="Échelle exponentielle de Rayleigh :" name="rayleigh_exponential_scale"/>
+ <slider label="Terme linéaire de Rayleigh :" name="rayleigh_linear"/>
+ <slider label="Terme constant de Rayleigh :" name="rayleigh_constant"/>
+ <slider label="Altitude maximum de Rayleigh :" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Terme exponentiel de mie :" name="mie_exponential"/>
+ <slider label="Échelle exponentielle de mie :" name="mie_exponential_scale"/>
+ <slider label="Terme linéaire de mie :" name="mie_linear"/>
+ <slider label="Terme constant de mie :" name="mie_constant"/>
+ <slider label="Facteur aniso de mie :" name="mie_aniso_factor"/>
+ <slider label="Altitude maximum de mie :" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Terme exponentiel d&apos;absorption :" name="absorption_exponential"/>
+ <slider label="Échelle exponentielle d&apos;absorption :" name="absorption_exponential_scale"/>
+ <slider label="Terme linéaire d&apos;absorption :" name="absorption_linear"/>
+ <slider label="Terme constant d&apos;absorption :" name="absorption_constant"/>
+ <slider label="Altitude maximale d&apos;absorption :" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/fr/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..39d87c9727
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Soleil et lune" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Afficher la balise" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Afficher la balise" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_settings_water.xml b/indra/newview/skins/default/xui/fr/panel_settings_water.xml
new file mode 100644
index 0000000000..203075f987
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Eau" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Décalage Fresnel :
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X :" name="water_normal_scale_x"/>
+ <slider label="Y :" name="water_normal_scale_y"/>
+ <slider label="Z :" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_tools_texture.xml b/indra/newview/skins/default/xui/fr/panel_tools_texture.xml
index 72c456aa6d..d028336ac7 100644
--- a/indra/newview/skins/default/xui/fr/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/fr/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Texture" name="Texture">
- <panel.string name="string repeats per meter">
- Répétitions au mètre
- </panel.string>
- <panel.string name="string repeats per face">
- Répétitions par face
- </panel.string>
<text name="color label">
Couleur
</text>
@@ -114,4 +108,5 @@
<spinner label="Décalage horizontal" name="shinyOffsetU"/>
<spinner label="Décalage vertical" name="shinyOffsetV"/>
<check_box initial_value="false" label="Aligner les faces Plan" name="checkbox planar align" tool_tip="Aligner les textures sur toutes les faces sélectionnées avec la dernière face sélectionnée. Application de la texture Plan requise."/>
+ <button label="Aligner" label_selected="Aligner les couches de texture actuelles" name="button align textures" tool_tip="Aligner les couches de texture actuelles"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/role_actions.xml b/indra/newview/skins/default/xui/fr/role_actions.xml
index d10de38437..95e4799ce4 100644
--- a/indra/newview/skins/default/xui/fr/role_actions.xml
+++ b/indra/newview/skins/default/xui/fr/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Modifier la musique et les médias" longdescription="Changez la musique et les médias à partir du menu À propos du terrain &gt; Médias." name="land change media" value="20"/>
<action description="Changer l&apos;option Modifier le terrain" longdescription="Changez l&apos;option Modifier le terrain à partir du menu À propos du terrain &gt; Options. Attention : ce pouvoir permet de terraformer votre terrain et de placer ou déplacer des plantes Linden. Assurez-vous de bien comprendre ce pouvoir avant de l&apos;attribuer. " name="land edit" value="21"/>
<action description="Changer diverses options du terrain" longdescription="Activez Sécurisé (pas de dégâts), Voler, et autorisez les autres résidents à : modifier le terrain, construire, créer des repères et exécuter des scripts sur les terrains appartenant au groupe dans l&apos;onglet propos du terrain &gt; Options." name="land options" value="22"/>
+ <action description="Modifier les paramètres environnementaux et le cycle du jour." longdescription="Charger les paramètres environnementaux et le cycle du jour à partir de l&apos;onglet A propos du terrain &gt; Environnement." name="land change environment" value="46"/>
</action_set>
<action_set description="Ces pouvoirs permettent aux membres d&apos;outrepasser les restrictions sur les parcelles du groupe." name="Parcel Powers">
<action description="Toujours autoriser Modifier le terrain" longdescription="Vous pouvez modifier le relief d&apos;une parcelle du groupe, même si l&apos;option est désactivée à partir du menu À propos du terrain &gt; Options." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 959494545a..f26eac545a 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -639,6 +639,15 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="BUTTON_HELP">
Afficher l&apos;aide
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Les éléments de ce type ne peuvent pas être attachés
+aux notes de cette région.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Seuls des éléments avec des autorisation
+illimitées pour le &apos;prochain propriétaire&apos;
+peuvent être joints aux notes.
+ </string>
<string name="Searching">
Recherche...
</string>
@@ -718,6 +727,18 @@ Veuillez réessayer de vous connecter dans une minute.
Erreur dans la demande de chargement. Veuillez consulter le site :
http://secondlife.com/support pour vous aider à résoudre ce problème.
</string>
+ <string name="SettingValidationError">
+ Échec de la validation pour l&apos;importation des paramètres [NAME]
+ </string>
+ <string name="SettingImportFileError">
+ Impossible d&apos;ouvre le fichier [FILE]
+ </string>
+ <string name="SettingParseFileError">
+ Impossible d&apos;ouvre le fichier [FILE]
+ </string>
+ <string name="SettingTranslateError">
+ Impossible de traduit les paramètres windlight hérités [NAME]
+ </string>
<string name="texture">
texture
</string>
@@ -793,6 +814,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="symbolic folder link">
lien du dossier
</string>
+ <string name="settings blob">
+ paramètres
+ </string>
<string name="mesh">
maillage
</string>
@@ -1123,6 +1147,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="ForceSitAvatar">
Forcez votre avatar à s’asseoir
</string>
+ <string name="ChangeEnvSettings">
+ Changer vos paramètres d&apos;environnement
+ </string>
<string name="NotConnected">
Pas connecté(e)
</string>
@@ -1274,6 +1301,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="tattoo">
Tatouage
</string>
+ <string name="universal">
+ Universel
+ </string>
<string name="physics">
Propriétés physiques
</string>
@@ -1316,6 +1346,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="tattoo_not_worn">
Tatouage non porté
</string>
+ <string name="universal_not_worn">
+ Universel non porté
+ </string>
<string name="physics_not_worn">
Propriétés physiques non portées
</string>
@@ -1367,6 +1400,9 @@ http://secondlife.com/support pour vous aider à résoudre ce problème.
<string name="create_new_tattoo">
Créer un nouveau tatouage
</string>
+ <string name="create_new_universal">
+ Créer un nouvel environnement universel
+ </string>
<string name="create_new_physics">
Créer de nouvelles propriétés physiques
</string>
@@ -1610,11 +1646,14 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life Ã
<string name="MarketplaceUpdating">
mise à jour...
</string>
+ <string name="UploadFeeInfo">
+ Les frais dépendent de votre niveau d'abonnement. Les niveaux supérieurs sont soumis à des frais moins élevés. [https://secondlife.com/my/account/membership.php? En savoir plus]
+ </string>
<string name="Open landmarks">
- Ouvrir les repères
+ Points de repère ouverts
</string>
<string name="Unconstrained">
- Sans contraintes
+ Sans contrainte
</string>
<string name="no_transfer" value=" (pas de transfert)"/>
<string name="no_modify" value=" (pas de modification)"/>
@@ -2514,6 +2553,27 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life Ã
<string name="RegionSettings">
Réglages de la région
</string>
+ <string name="NoEnvironmentSettings">
+ Cette région ne prend pas en charge les paramètres environnementaux.
+ </string>
+ <string name="EnvironmentSun">
+ Soleil
+ </string>
+ <string name="EnvironmentMoon">
+ Lune
+ </string>
+ <string name="EnvironmentBloom">
+ Éclat
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Bruit du nuage
+ </string>
+ <string name="EnvironmentNormalMap">
+ Carte normale
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparent
+ </string>
<string name="ClassifiedClicksTxt">
Clics : [TELEPORT] téléportation, [MAP] carte, [PROFILE] profil
</string>
@@ -4730,6 +4790,9 @@ du rapport d&apos;infraction
<string name="New Tattoo">
Nouveau tatouage
</string>
+ <string name="New Universal">
+ Nouvel environnement universel
+ </string>
<string name="New Physics">
Nouvelles propriétés physiques
</string>
@@ -4856,6 +4919,15 @@ du rapport d&apos;infraction
<string name="Female - Wow">
Femme - Ouah !
</string>
+ <string name="New Daycycle">
+ Nouveau cycle du jour
+ </string>
+ <string name="New Water">
+ Nouvelle eau
+ </string>
+ <string name="New Sky">
+ Nouveau ciel
+ </string>
<string name="/bow">
/s&apos;incliner
</string>
@@ -5028,6 +5100,15 @@ Veuillez vous reporter à http://status.secondlifegrid.net afin de déterminer s
<string name="Chat" value=" Chat :">
Chat
</string>
+ <string name="BaseMembership">
+ Base
+ </string>
+ <string name="PremiumMembership">
+ Premium
+ </string>
+ <string name="Premium PlusMembership">
+ Premium Plus
+ </string>
<string name="DeleteItems">
Supprimer les articles sélectionnés ?
</string>
@@ -5384,6 +5465,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="BeaconMedia">
Affichage des balises de média (blanc)
</string>
+ <string name="BeaconSun">
+ Balise de visibilité du soleil (orange)
+ </string>
+ <string name="BeaconMoon">
+ Observation de la balise de direction de la lune (violet)
+ </string>
<string name="ParticleHiding">
Masquage des particules
</string>
@@ -5411,6 +5498,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Command_Destinations_Label">
Destinations
</string>
+ <string name="Command_Environments_Label">
+ Mes environnements
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5504,6 +5597,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Command_Destinations_Tooltip">
Destinations intéressantes
</string>
+ <string name="Command_Environments_Tooltip">
+ Mes environnements
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Publier sur Facebook
+ </string>
<string name="Command_Flickr_Tooltip">
Charger sur Flickr
</string>
@@ -5699,6 +5798,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="ExperiencePermission12">
accepter automatiquement les permissions d’expérience
</string>
+ <string name="ExperiencePermission16">
+ forcez votre avatar à s’asseoir
+ </string>
+ <string name="ExperiencePermission17">
+ changer vos paramètres d&apos;environnement
+ </string>
<string name="ExperiencePermissionShortUnknown">
a effectué une opération inconnue : [Permission]
</string>
@@ -5723,6 +5828,12 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="ExperiencePermissionShort12">
Permission
</string>
+ <string name="ExperiencePermissionShort16">
+ M&apos;asseoir
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Environnement
+ </string>
<string name="logging_calls_disabled_log_empty">
Les conversations ne sont pas archivées. Pour commencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences &gt; Chat.
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml
index 0a7837e122..03e03095d6 100644
--- a/indra/newview/skins/default/xui/it/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_about_land.xml
@@ -367,11 +367,11 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
Fotografia:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clicca per scegliere una immagine"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Gli avatar di altri lotti possono vedere gli avatar che si trovano in questo lotto e chattare con loro
</text>
- <check_box label="Vedi avatar" name="SeeAvatarsCheck" tool_tip="Consente ad avatar in altri lotti di vedere e chattare con avatar in questo lotto e viceversa."/>
- <text name="landing_point">
+ <check_box label="Vedi avatar" top="170" name="SeeAvatarsCheck" tool_tip="Consente ad avatar in altri lotti di vedere e chattare con avatar in questo lotto e viceversa."/>
+ <text name="landing_point" width="225">
Punto di atterraggio: [LANDING]
</text>
<button label="Imposta" label_selected="Imposta" name="Set" tool_tip="Imposta il punto di atterraggio dove arrivano i visitatori. Impostalo nel punto dove si trova il tuo avatar in questo terreno." width="60"/>
@@ -449,7 +449,7 @@ Media:
<panel.string name="estate_override">
Una o più di queste impostazioni sono già impostate a livello regionale
</panel.string>
- <check_box label="Chiunque può visitare (Se si rimuove la selezione vengono create linee di espulsione)" name="public_access"/>
+ <check_box label="Chiunque può visitare" tool_tip="Se si rimuove la selezione vengono create linee di espulsione" name="public_access"/>
<check_box label="È necessario avere più di 18 anni [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="È necessario aver registrato le informazioni di pagamento [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Per poter visitare questo lotto i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="Consenti gruppo [GRUPPO] senza restrizioni" name="GroupCheck" tool_tip="Imposta il gruppo nel pannello generale."/>
@@ -484,5 +484,6 @@ Media:
</panel>
</panel>
<panel label="ESPERIENZE" name="land_experiences_panel"/>
+ <panel label="AMBIENTE" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_adjust_environment.xml b/indra/newview/skins/default/xui/it/floater_adjust_environment.xml
new file mode 100644
index 0000000000..948e2d03aa
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Illuminazione personale">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Reimposta" name="btn_reset" tool_tip="Chiudi e reimposta a Ambiente Condiviso"/>
+ <text name="cloud_map_label">
+ Immagine nuvola:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Sole:
+ </text>
+ <check_box label="Mostra marcatore" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Mostra marcatore" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_beacons.xml b/indra/newview/skins/default/xui/it/floater_beacons.xml
index b7ab265cc2..303c2fdd6c 100644
--- a/indra/newview/skins/default/xui/it/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/it/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Fonti sonore" name="sounds"/>
<check_box label="Fonti delle particelle" name="particles"/>
<check_box label="Fonti multimedia" name="moapbeacon"/>
+ <check_box label="Sole" name="sun"/>
+ <check_box label="Luna" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_bulk_perms.xml b/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
index 10bbe933e3..b7572f1776 100644
--- a/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="Suoni"/>
<check_box label="Texture" name="check_texture"/>
<icon name="icon_texture" tool_tip="Texture"/>
+ <icon name="icon_setting" tool_tip="Impostazioni ambiente"/>
<button label="√ Tutti" label_selected="Tutti" name="check_all"/>
<button label="Cancella" label_selected="Nessuno" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
index 743969f557..522d26373e 100644
--- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
@@ -60,8 +60,7 @@ l&apos;oggetto.
</text>
<button label="Acquista" name="buy_btn"/>
<button label="Annulla" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5">
+ <floater.string name="info_cannot_buy" left="160" font="SansSerifBig">
Non in grado di acquistare
- </text>
- <button label="Continua sul Web" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml
deleted file mode 100644
index 31cf01fc7b..0000000000
--- a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="CANCELLA VALORE PREDEFINITO AMB">
- <string name="title_water">
- Cancella valore predefinito acqua
- </string>
- <string name="title_sky">
- Cancella valore predefinito cielo
- </string>
- <string name="title_day_cycle">
- Cancella ciclo giornata
- </string>
- <string name="label_water">
- Valore predefinito:
- </string>
- <string name="label_sky">
- Valore predefinito:
- </string>
- <string name="label_day_cycle">
- Ciclo giornata:
- </string>
- <string name="msg_confirm_deletion">
- Sei sicuro di volere eliminare il valore predefinito selezionato?
- </string>
- <string name="msg_sky_is_referenced">
- Impossibile rimuovere un valore predefinito che viene utilizzato in uno o più cicli di giornata.
- </string>
- <string name="combo_label">
- -Seleziona un valore predefinito-
- </string>
- <text name="label">
- Valore predefinito:
- </text>
- <button label="Elimina" name="delete"/>
- <button label="Annulla" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/it/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..12efdb81b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Modifica ciclo giornata">
+ <string name="title_new">
+ Crea un nuovo ciclo giornata
+ </string>
+ <string name="title_edit">
+ Modifica ciclo giornata
+ </string>
+ <string name="hint_new">
+ Dai un nome al ciclo della giornata, regola i comandi per crearlo e fai clic su &quot;Salva&quot;.
+ </string>
+ <string name="hint_edit">
+ Per modificare il ciclo della giornata, regola i comandi seguenti e fai clic su &quot;Salva&quot;.
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Cielo [ALT]
+ </string>
+ <string name="sky_label">
+ Cielo
+ </string>
+ <string name="water_label">
+ Acqua
+ </string>
+ <string name="commit_parcel">
+ Applica al lotto
+ </string>
+ <string name="commit_region">
+ Applica alla regione
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Nome ciclo giornata:
+ </text>
+ <button label="Importa" name="btn_import" tool_tip="Importa impostazioni legacy dal disco."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Cielo 4:" name="sky4_track"/>
+ <button label="Cielo 3:" name="sky3_track"/>
+ <button label="Cielo 2:" name="sky2_track"/>
+ <button label="Suolo" name="sky1_track"/>
+ <button label="Acqua" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Clona Percorso Da" name="copy_track"/>
+ <button label="Carica Percorso Da" name="load_track"/>
+ <button label="Cancella Percorso" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Passo indietro"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Passo avanti"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="Aggiungi [FRAME]" name="add_frame"/>
+ <button label="Carica [FRAME]" name="btn_load_frame"/>
+ <button label="Elimina [FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Seleziona un fotogramma chiave dalla cronologia degli eventi qui sopra per modificare le impostazioni.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Acqua" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmosfera e illuminazione" name="atmosphere_panel"/>
+ <panel label="Nuvole" name="clouds_panel"/>
+ <panel label="Sole e Luna" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Salva" name="save_btn"/>
+ <button label="Annulla" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/it/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..4ca13a5891
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Ambiente stabilito">
+ <string name="edit_sky">
+ Modifica cielo:
+ </string>
+ <string name="edit_water">
+ Modifica acqua:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Carica" name="btn_load" tool_tip="Carica impostazioni dall’inventario"/>
+ <button label="Importa" name="btn_import" tool_tip="Importa impostazioni legacy dal disco."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Salva" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Annulla" name="btn_cancel" tool_tip="Ripristina l&apos;ultima versione salvata"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
index fe41b8ca65..c12c031198 100644
--- a/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
@@ -12,6 +12,7 @@
<check_box label="Suoni" name="check_sound"/>
<check_box label="Texture" name="check_texture"/>
<check_box label="Fotografie" name="check_snapshot"/>
+ <check_box label="Impostazioni" name="check_settings"/>
<button label="Tutto" label_selected="Tutto" name="All"/>
<button label="Nulla" label_selected="Nulla" name="None"/>
<check_box label="Mostra sempre le cartelle" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
deleted file mode 100644
index 7a1f7f0a0c..0000000000
--- a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="CASELLA IN USCITA DEL RIVENDITORE">
- <string name="OutboxFolderCount1">
- 1 cartella
- </string>
- <string name="OutboxFolderCountN">
- [NUM] cartelle
- </string>
- <string name="OutboxImporting">
- Invio cartelle...
- </string>
- <string name="OutboxInitializing">
- Inizializzazione...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Caricamento in corso...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Trascina elementi qui per creare cartelle
- </text>
- </panel>
- <button label="Invia a Marketplace" name="outbox_import_btn" tool_tip="Push su negozio Marketplace"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_my_environments.xml b/indra/newview/skins/default/xui/it/floater_my_environments.xml
new file mode 100644
index 0000000000..bcbf4613f3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Luoghi" name="my_environments" title="I MIEI AMBIENTI">
+ <layout_stack>
+ <layout_panel label="Filtri" name="filter_panel">
+ <check_box label="Giorni" name="chk_days"/>
+ <check_box label="Cieli" name="chk_skies"/>
+ <check_box label="Acqua" name="chk_water"/>
+ <filter_editor label="Filtra Ambienti" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Ambienti" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Mostra tutte le cartelle" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Altre opzioni"/>
+ <menu_button name="btn_newsettings" tool_tip="Crea nuova impostazione"/>
+ <button name="btn_del" tool_tip="Rimuovi l&apos;articolo selezionato"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_perms_default.xml b/indra/newview/skins/default/xui/it/floater_perms_default.xml
index 9a88f53d47..bdfea6d0ad 100644
--- a/indra/newview/skins/default/xui/it/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/it/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Imposta autorizzazioni predefinite per la creazione di vestiti o parti del corpo">
Indossabili
</text>
+ <text name="label_13" tool_tip="Imposta autorizzazioni predefinite per la creazione delle impostazioni dell’Ambiente">
+ Impostazioni
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Annulla" label_selected="Annulla" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/it/floater_pick_track.xml b/indra/newview/skins/default/xui/it/floater_pick_track.xml
new file mode 100644
index 0000000000..8e1f3d7065
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="PREFERITO: PERCORSO">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Seleziona fonte cielo:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Cielo4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Cielo3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Cielo2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Suolo" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Annulla" label_selected="Annulla" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml
index 3773ef3711..53f9ebc6fd 100644
--- a/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/it/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Acqua trasparente" name="TransparentWater"/>
<check_box initial_value="true" label="Mappatura urti e brillantezza" name="BumpShiny"/>
<check_box initial_value="true" label="Luci locali" name="LocalLights"/>
- <check_box initial_value="true" label="Shader di base" name="BasicShaders" tool_tip="Se si disattiva questa opzione, si possono evitare interruzioni nei driver di alcune schede grafiche"/>
<slider label="Dettagli terreno:" name="TerrainDetail"/>
<text name="TerrainDetailText">
Basso
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 5b4054514e..8e8d020067 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
@@ -10,7 +10,7 @@
Descrizione:
</text>
<text name="dimensions">
- [WIDTH] px x [HEIGHT] px
+ [WIDTH]px x [HEIGHT]px
</text>
<text name="aspect_ratio">
Antreprima rapporto di visualizzazione
diff --git a/indra/newview/skins/default/xui/it/floater_settings_picker.xml b/indra/newview/skins/default/xui/it/floater_settings_picker.xml
new file mode 100644
index 0000000000..31dfb6ef19
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="PREFERITO: IMPOSTAZIONI">
+ <floater.string name="pick title">
+ Preferito:
+ </floater.string>
+ <floater.string name="pick_track">
+ SELEZIONA PERCORSO
+ </floater.string>
+ <floater.string name="pick_settings">
+ SELEZIONA IMPOSTAZIONI
+ </floater.string>
+ <floater.string name="track_water">
+ Acqua
+ </floater.string>
+ <floater.string name="track_ground">
+ Suolo
+ </floater.string>
+ <floater.string name="track_sky">
+ Cielo[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Filtro texture" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Annulla" label_selected="Annulla" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
index 27a17868a7..f857bfe49f 100644
--- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
@@ -9,17 +9,13 @@
<text name="Multiple">
Texture multiple
</text>
- <radio_group name="mode_selection">
- <radio_item label="Inventario" name="inventory" value="0"/>
- <radio_item label="Locale" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Dimensioni: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Inventario" name="inventory" value="0"/>
+ <combo_box.item label="Locale" name="local" value="1"/>
+ </combo_box>
<button label="Default" label_selected="Default" name="Default"/>
<button label="Vuoto" label_selected="Vuoto" name="Blank"/>
<button label="Niente" label_selected="Niente" name="None"/>
- <check_box initial_value="true" label="Applica adesso" name="apply_immediate_check"/>
<text name="preview_disabled" value="Anteprima disattivata"/>
<filter_editor label="Filtro texture" name="inventory search editor"/>
<check_box initial_value="false" label="Mostra cartelle" name="show_folders_check"/>
@@ -30,6 +26,22 @@
<column label="Nome" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Scegli la bake della texture">
+ <combo_box.item label="Nessuna" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Nascondi regione mesh base" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="Annulla" label_selected="Annulla" name="Cancel"/>
+ <check_box initial_value="true" label="Applica adesso" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
index 699490c8f1..8861cc726f 100644
--- a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Tocca" name="touch_attach" />
+ <menu_item_call label="Modifica" name="edit_item" />
<menu_item_call label="Stacca" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml
index de6855ca97..d2fbcafe97 100644
--- a/indra/newview/skins/default/xui/it/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Attiva" name="Marketplace Activate"/>
<menu_item_call label="Disattiva" name="Marketplace Deactivate"/>
<menu_item_call label="Condividi" name="Share"/>
- <menu_item_call label="Compra" name="Task Buy"/>
<menu_item_call label="Apri" name="Task Open"/>
<menu_item_call label="Esegui" name="Task Play"/>
<menu_item_call label="Proprietà" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Nuove mutande" name="New Underpants"/>
<menu_item_call label="Nuovo Alfa Mask" name="New Alpha Mask"/>
<menu_item_call label="Nuovo tatuaggio" name="New Tattoo"/>
+ <menu_item_call label="Nuovo Universale" name="New Universal"/>
<menu_item_call label="Nuova fisica" name="New Physics"/>
</menu>
<menu label="Nuove parti del corpo" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Nuovi capelli" name="New Hair"/>
<menu_item_call label="Nuovi occhi" name="New Eyes"/>
</menu>
+ <menu label="Nuove impostazioni" name="New Settings">
+ <menu_item_call label="Nuovo cielo" name="New Sky"/>
+ <menu_item_call label="Nuova acqua" name="New Water"/>
+ <menu_item_call label="Nuovo ciclo giornata" name="New Day Cycle"/>
+ </menu>
<menu label="Usa come impostazione predefinita per" name="upload_def">
<menu_item_call label="Caricamenti immagini" name="Image uploads"/>
<menu_item_call label="Caricamenti suoni" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Indossa" name="Wearable And Object Wear"/>
<menu label="Attacca a" name="Attach To"/>
<menu label="Attacca all&apos;HUD" name="Attach To HUD"/>
+ <menu_item_call label="Tocca" name="Attachment Touch" />
<menu_item_call label="Modifica" name="Wearable Edit"/>
<menu_item_call label="Aggiungi" name="Wearable Add"/>
<menu_item_call label="Togli" name="Take Off"/>
+ <menu_item_call label="Applica solo a me stesso" name="Settings Apply Local"/>
+ <menu_item_call label="Applica al lotto" name="Settings Apply Parcel"/>
<menu_item_call label="Copia negli annunci Marketplace" name="Marketplace Copy"/>
<menu_item_call label="Sposta negli annunci Marketplace" name="Marketplace Move"/>
<menu_item_call label="--nessuna opzione--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/it/menu_inventory_add.xml b/indra/newview/skins/default/xui/it/menu_inventory_add.xml
index 62da61cd6b..6f9212f56b 100644
--- a/indra/newview/skins/default/xui/it/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Suono ([COST]L$)..." name="Upload Sound"/>
<menu_item_call label="Animazione ([COST]L$)..." name="Upload Animation"/>
<menu_item_call label="Modella..." name="Upload Model"/>
- <menu_item_call label="Procedura guidata modellazione..." name="Upload Model Wizard"/>
- <menu_item_call label="In blocco ([COST]L$ per file)..." name="Bulk Upload"/>
- <menu_item_call label="Definisci diritti di caricamento predefiniti" name="perm prefs"/>
+ <menu_item_call label="In blocco..." name="Bulk Upload"/>
</menu>
<menu_item_call label="Nuova cartella" name="New Folder"/>
<menu_item_call label="Nuovo script" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Nuovi slip" name="New Underpants"/>
<menu_item_call label="Nuovo Alfa (trasparenza)" name="New Alpha"/>
<menu_item_call label="Nuovo tatuaggio" name="New Tattoo"/>
+ <menu_item_call label="Nuovo Universale" name="New Universal"/>
<menu_item_call label="Nuova fisica" name="New Physics"/>
</menu>
<menu label="Nuove parti del corpo" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Nuovi capelli" name="New Hair"/>
<menu_item_call label="Nuovi occhi" name="New Eyes"/>
</menu>
+ <menu label="Nuove impostazioni" name="New Settings">
+ <menu_item_call label="Nuovo cielo" name="New Sky"/>
+ <menu_item_call label="Nuova acqua" name="New Water"/>
+ <menu_item_call label="Nuovo ciclo giornata" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
index 62c6d53e1c..cf45fec09e 100644
--- a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Nuovo Alpha (trasparenza)" name="New Alpha"/>
<menu_item_call label="Nuova fisica" name="New Physics"/>
<menu_item_call label="Nuovo tatuaggio" name="New Tattoo"/>
+ <menu_item_call label="Nuovo Universale" name="New Universal"/>
</menu>
<menu label="Nuove parti del corpo" name="New Body Parts">
<menu_item_call label="Nuova figura corporea" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/it/menu_save_settings.xml b/indra/newview/skins/default/xui/it/menu_save_settings.xml
new file mode 100644
index 0000000000..80c0ef90a6
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Salva" name="save_settings"/>
+ <menu_item_check label="Salva con nome" name="save_as_new_settings"/>
+ <menu_item_check label="Esegui" name="commit_changes"/>
+ <menu_item_check label="Applica solo a me stesso" name="apply_local"/>
+ <menu_item_check label="Applica al lotto" name="apply_parcel"/>
+ <menu_item_check label="Applica alla regione" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_settings_add.xml b/indra/newview/skins/default/xui/it/menu_settings_add.xml
new file mode 100644
index 0000000000..69fcacc374
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Nuovo cielo" name="New Sky"/>
+ <menu_item_call label="Nuova acqua" name="New Water"/>
+ <menu_item_call label="Nuovo ciclo giornata" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_settings_gear.xml b/indra/newview/skins/default/xui/it/menu_settings_gear.xml
new file mode 100644
index 0000000000..6a879814fc
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Modifica" name="edit_settings"/>
+ <menu_item_call label="Applica solo a me stesso" name="Settings Apply Local"/>
+ <menu_item_call label="Applica al lotto" name="Settings Apply Parcel"/>
+ <menu_item_call label="Applica alla regione" name="Settings Apply Region"/>
+ <menu_item_call label="Copia" name="copy_settings"/>
+ <menu_item_call label="Incolla" name="paste_settings"/>
+ <menu_item_call label="Copia UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index ae82a89d28..c7a10df910 100644
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="Proprietà del lotto" name="Parcel Properties"/>
<menu_item_check label="Menu Avanzato" name="Show Advanced Menu"/>
</menu>
- <menu label="Dom" name="Sun">
+ <menu label="Ambiente" name="Environment">
<menu_item_check label="Alba" name="Sunrise"/>
<menu_item_check label="Mezzogiorno" name="Noon"/>
<menu_item_check label="Tramonto" name="Sunset"/>
<menu_item_check label="Mezzanotte" name="Midnight"/>
- <menu_item_check label="Usa impostazioni regione" name="Use Region Settings"/>
- </menu>
- <menu label="Editor ambiente" name="Environment Editor">
- <menu_item_call label="Impostazioni ambiente..." name="Environment Settings"/>
- <menu label="Valori predefiniti acqua" name="Water Presets">
- <menu_item_call label="Nuovo valore predefinito..." name="new_water_preset"/>
- <menu_item_call label="Modifica valore predefinito..." name="edit_water_preset"/>
- <menu_item_call label="Elimina valore predefinito..." name="delete_water_preset"/>
- </menu>
- <menu label="Valori predefiniti cielo" name="Sky Presets">
- <menu_item_call label="Nuovo valore predefinito..." name="new_sky_preset"/>
- <menu_item_call label="Modifica valore predefinito..." name="edit_sky_preset"/>
- <menu_item_call label="Elimina valore predefinito..." name="delete_sky_preset"/>
- </menu>
- <menu label="Valori predefiniti giorno" name="Day Presets">
- <menu_item_call label="Nuovo valore predefinito..." name="new_day_preset"/>
- <menu_item_call label="Modifica valore predefinito..." name="edit_day_preset"/>
- <menu_item_call label="Elimina valore predefinito..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Utilizza ambienti condivisi" name="Use Shared Environment"/>
+ <menu_item_call label="I miei ambienti..." name="my_environs"/>
+ <menu_item_call label="Illuminazione personale..." name="adjustment_tool"/>
+ <menu_item_check label="Ferma nuvole" name="pause_clouds"/>
</menu>
</menu>
<menu label="Costruisci" name="BuildTools">
@@ -168,7 +153,7 @@
<menu_item_call label="Suono ([COST] L$)..." name="Upload Sound"/>
<menu_item_call label="Animazione ([COST] L$)..." name="Upload Animation"/>
<menu_item_call label="Modella..." name="Upload Model"/>
- <menu_item_call label="In blocco ([COST] L$ per file)..." name="Bulk Upload"/>
+ <menu_item_call label="In blocco..." name="Bulk Upload"/>
</menu>
<menu_item_call label="Annulla" name="Undo"/>
<menu_item_call label="Ripeti" name="Redo"/>
@@ -323,6 +308,9 @@
<menu_item_check label="Maschera alfa automatica (non differita)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texture delle animazioni" name="Animation Textures"/>
<menu_item_check label="Disabilita texture" name="Disable Textures"/>
+ <menu_item_check label="Disattiva Ambiente" name="Disable Ambient"/>
+ <menu_item_check label="Disattiva luce del sole" name="Disable Sunlight"/>
+ <menu_item_check label="Disattiva Luci locali" name="Disable Local Lights"/>
<menu_item_check label="Rendering delle luci unite" name="Render Attached Lights"/>
<menu_item_check label="Rendering particelle unite" name="Render Attached Particles"/>
<menu_item_check label="Gli oggetti brillano quando sono sotto il cursore" name="Hover Glow Objects"/>
@@ -413,6 +401,7 @@
</menu>
<menu label="Admin" name="Deprecated">
<menu label="Take Off Clothing" name="Take Off Clothing">
+ <menu_item_call label="Universale" name="Universal"/>
<menu_item_call label="Fisica" name="Physics"/>
</menu>
<menu label="Guida" name="DeprecatedHelp">
diff --git a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
index c9a02d8a86..23abdd7bf2 100644
--- a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Sostituisci" name="wear_replace"/>
<menu_item_call label="Indossa" name="wear_wear"/>
<menu_item_call label="Aggiungi" name="wear_add"/>
+ <menu_item_call label="Tocca" name="touch" />
<menu_item_call label="Togli / Stacca" name="take_off_or_detach"/>
<menu_item_call label="Stacca" name="detach"/>
<context_menu label="Attacca a" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
index de25f88aca..2f3a2aea43 100644
--- a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Modifica vestiario" name="edit"/>
+ <menu_item_call label="Tocca" name="touch"/>
+ <menu_item_call label="Modifica" name="edit_item"/>
+ <menu_item_call label="Modifica vestiario" name="edit_outfit"/>
<menu_item_call label="Togli" name="takeoff"/>
<menu_item_call label="Copia gruppo vestiti negli Appunti" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
index ec375e5240..08b56888a3 100644
--- a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Tocca" name="touch_attach"/>
<menu_item_call label="Togli" name="take_off"/>
<menu_item_call label="Stacca" name="detach"/>
- <menu_item_call label="Modifica vestiario" name="edit"/>
+ <menu_item_call label="Modifica vestiario" name="edit_outfit"/>
<menu_item_call label="Modifica" name="edit_item"/>
<menu_item_call label="Mostra originale" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index d7be208c51..1c43013255 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -266,6 +266,10 @@ Vuoi concedere i diritti di modifica ai residenti selezionati?
Vuoi revocare i permessi di modifica dati ai residenti selezionati?
<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ Il nome di un gruppo deve essere compreso tra [MIN_LEN] e [MAX_LEN] caratteri.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
Non è possibile creare il gruppo.
[MESSAGE]
@@ -360,7 +364,7 @@ Vuoi continuare?
Non hai abbastanza L$ per iscriverti a questo gruppo.
</notification>
<notification name="CreateGroupCost">
- La creazione di questo gruppo costerà L$ 100.
+ La creazione di questo gruppo ti costerà [COST]L$.
I gruppi devono avere più di un partecipante, o saranno eliminati definitivamente.
Invita altri partecipanti entro le prossime 48 ore.
<usetemplate canceltext="Annulla" name="okcancelbuttons" notext="Annulla" yestext="Crea un gruppo per L$ 100"/>
@@ -501,6 +505,9 @@ Per collocare il media su una sola faccia, scegli Seleziona faccia, clicca su un
<notification name="ErrorEncodingSnapshot">
Errore nella codifica della fotografia.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Ti serviranno [COST]L$ per caricare questo articolo.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Hai bisogno di L$ [COST] per salvare una foto nel tuo inventario. Puoi acquistare L$ o salvare la foto sul tuo computer.
</notification>
@@ -1740,11 +1747,14 @@ Vuoi cancellare quell&apos;elemento?
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- Il numero massimo di gruppi per gli account Basic è [MAX_BASIC] e
-per gli account [https://secondlife.com/premium/ Premium] è [MAX_PREMIUM].
-Se hai ridotto il livello del tuo account, dovrai essere iscritto a meno di [MAX_BASIC] gruppi prima di poter iscriverti a un nuovo gruppo.
-
-[https://secondlife.com/my/account/membership.php Passa a un livello superiore oggi stesso!]
+ I residenti con un'iscrizione Base possono aderire fino a [MAX_BASIC] gruppi.
+Le iscrizioni Premium consentono fino a [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Per saperne di più o per l'aggiornamento]
+ <usetemplate name="okbutton" yestext="Chiudi"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ I residenti con un'iscrizione Base possono aderire fino a [MAX_BASIC] gruppi.
+Le iscrizioni Premium consentono fino a [MAX_PREMIUM]. Le iscrizioni Premium Plus
+consentono fino a [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Per saperne di più o per l'aggiornamento]
<usetemplate name="okbutton" yestext="Chiudi"/>
</notification>
<notification name="KickUser">
@@ -1963,6 +1973,10 @@ Cambierà migliaia di regioni e produrrà seri problemi ai vari server.
Togliendo la spunta a questa opzione potrebbero essere rimosse le restrizioni che i proprietari di lotti hanno aggiunto per tenere lontani disturbatori, mantenere la privacy, o evitare che minorenni abbiano accesso a materiale per adulti. Parla con i proprietari del tuo lotto se ce n’è bisogno.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Togliendo la spunta a questa opzione potrebbero essere rimossi gli ambienti personalizzati che i proprietari hanno aggiunto ai loro lotti. Parlane con i proprietari del tuo lotto se ce n’è bisogno. Vuoi continuare?
+ <usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
<usetemplate name="okbutton" yestext="OK"/>
@@ -2443,7 +2457,15 @@ Inseriscilo in una pagina web per dare ad altri un accesso facile a questa ubica
Questo file di ciclo giornaliero fa riferimento ad un file di cielo mancante: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- Queste impostazioni non possono essere applicare alla regione. Uscendo dalla regione e ritornandoci potrebbe risolvere il problema. Il motivo fornito: [FAIL_REASON]
+ Siamo spiacenti, queste impostazioni non possono essere applicate alla regione. Motivo: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Una texture Locale è in uso nel percorso [TRACK], fotogramma #[FRAMENO] ([FRAME%]) nel campo [FIELD].
+Utilizzando texture locali potrebbero non venire salvate le impostazioni.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Una texture Locale è in uso nel campo [FIELD].
+Utilizzando texture locali potrebbero non venire salvate le impostazioni.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Impossibile cancellare l&apos;ultima chiave in questo ciclo giornata. Il ciclo giornata non può essere vuoto. Invece di cancellare la chiave restante, modificala e quindi creane una nuova.
@@ -3294,6 +3316,22 @@ Per sicurezza, verranno bloccati per alcuni secondi.
La tua voce è stata interrotta dal moderatore.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Purtroppo non siamo stati in grado di ottenere informazioni utili per questa sessione. Questo non dovrebbe accadere in un normale ambiente di produzione. Si prega di contattare il supporto. Questa sessione non funzionerà correttamente, si consiglia di riavviare.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Questo caricherà [COUNT] oggetti a un costo totale di [COST]L$. Vuoi continuare con il caricamento?
+ <usetemplate name="okcancelbuttons" notext="Annulla" yestext="Carica"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ I file selezionati non possono essere caricati.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Alcuni dei file selezionati non possono essere caricati.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
Questo caricamento costerà L$[PRICE]. Continuare con il caricamento?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Carica"/>
@@ -4388,4 +4426,75 @@ Prova a selezionare un pezzo di terreno più piccolo.
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ Non abbiamo potuto caricare le impostazioni per [NAME] dal database.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Impossibile applicare le impostazioni all’ambiente.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Impossibile applicare le impostazioni all’ambiente.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Questa regione non supporta le impostazioni per l’ambiente.
+ </notification>
+ <notification label="Salva Outfit" name="SaveSettingAs">
+ Salva con nome le impostazioni attuali dell’ambiente:
+ <form name="form">
+ <input name="message">
+ [DESC] (nuovo)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Annulla"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Impossibile importare le impostazioni legacy vento e luce [NAME] da
+[FILE].
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Impossibile impostare l’ambiente per questo lotto.
+Inserisci o seleziona un lotto che hai il permesso di modificare.
+ </notification>
+ <notification name="SettingsUnsuported">
+ Questa regione non supporta le impostazioni.
+Spostati in una regione che abbia le impostazioni abilitate e riprova.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Stai per perdere le modifiche che hai fatto a questo [TYPE] chiamato &quot;[NAME]&quot;.
+Vuoi continuare?
+ <usetemplate ignoretext="Sei sicuro di voler perdere le modifiche apportate?" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Stai per rimuovere tutte le impostazioni applicate.
+Vuoi continuare?
+ <usetemplate name="okcancelbuttons" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Stai per rimuovere tutte le Impostazioni personali illuminazione. Vuoi continuare?
+ <usetemplate name="okcancelbuttons" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Stai per importare impostazioni non trasferibili in questo ciclo giornata. Continuando, anche le impostazioni che stai modificando diventeranno non trasferibili.
+
+Questo cambiamento non può essere annullato.
+
+Vuoi continuare?
+ <usetemplate ignoretext="Sei sicuro di voler rendere le impostazioni non trasferibili?" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Non puoi modificare le impostazioni direttamente dalla raccolta.
+Copia nell’inventario e prova ancora.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Abbiamo riscontrato un problema con queste impostazioni. Non possono essere salvate o applicate in questo momento.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Impossibile caricare il percorso in [TRACK].
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Impossibile caricare il percorso da [TRACK1] a [TRACK2].
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
index d76fb62c53..79938b79dc 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Tatuaggio della testa" name="Head Tattoo" tool_tip="Clicca per scegliere una fotografia"/>
- <texture_picker label="Tatuaggio superiore" name="Upper Tattoo" tool_tip="Clicca per scegliere una fotografia"/>
- <texture_picker label="Tattuaggio inferiore" name="Lower Tattoo" tool_tip="Clicca per scegliere una fotografia"/>
- <color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Tatuaggio testa" name="Head Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio parte alta" name="Upper Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio parte bassa" name="Lower Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Fai clic per aprire il selettore dei colori"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_universal.xml b/indra/newview/skins/default/xui/it/panel_edit_universal.xml
new file mode 100644
index 0000000000..10fab0e8be
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Tatuaggio testa" name="Head Universal Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio parte alta" name="Upper Universal Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio parte bassa" name="Lower Universal Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio gonna" name="Skirt Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio capelli" name="Hair Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio occhi" name="Eyes Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio braccio sinistro" name="Left Arm Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio gamba sinistra" name="Left Leg Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio Aux1" name="Aux1 Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio Aux2" name="Aux2 Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <texture_picker label="Tatuaggio Aux3" name="Aux3 Tattoo" tool_tip="Fai clic per scegliere un’immagine"/>
+ <color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Fai clic per aprire il selettore dei colori"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
index e54dc26d05..83824591d6 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Modifica del tatuaggio
</string>
+ <string name="edit_universal_title">
+ Modifica Universale:
+ </string>
<string name="edit_physics_title">
Modifica fisica
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Tatuaggio:
</string>
+ <string name="universal_desc_text">
+ Universale:
+ </string>
<string name="physics_desc_text">
Fisica:
</string>
diff --git a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
deleted file mode 100644
index af5e05336e..0000000000
--- a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Trascina gli oggetti qui per prepararli per la vendita nel tuo negozio"/>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 38a03fb4d2..3df2368ae0 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -18,7 +18,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<string name="no_groups_msg" value="Stai cercando gruppi di cui far parte? Prova [secondlife:///app/search/groups Cerca]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Fai doppio clic per aprire la Mappa, premi il tasto Maiusc e trascina per la panoramica)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Fai doppio clic per teleportarti, premi il tasto Maiusc e trascina per la panoramica)"/>
- <string name="GroupCountWithInfo" value="Fai parte di [COUNT] gruppi e puoi iscriverti a [REMAINING] altri. [secondlife:/// Ne vuoi altri?]"/>
+ <string name="GroupCountWithInfo" value="Fai parte di [COUNT] gruppi e puoi ancora unirti a [REMAINING] gruppi. [secondlife:/// Aumenta il tuo limite]"/>
<tab_container name="tabs">
<panel label="NELLE VICINANZE" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<dnd_button name="minus_btn" tool_tip="Lascia il gruppo selezionato"/>
</panel>
<text name="groupcount">
- Fai parte di [COUNT] gruppi e puoi iscriverti a [REMAINING] altri.
+ Fai parte di [COUNT] gruppi e puoi ancora unirti a [REMAINING] gruppi.
</text>
</panel>
<panel label="RECENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
index f3ca9fafb3..c7739b8472 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
@@ -32,10 +32,10 @@
</text>
<check_box initial_value="true" label="Esegui sempre il rendering degli amici" name="AlwaysRenderFriends"/>
<button label="Eccezioni..." name="RenderExceptionsButton"/>
- <button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/>
- <button label="Carica valore predefinito..." name="PrefLoadButton"/>
+ <button label="Salva impostazioni come valori predefiniti" name="PrefSaveButton" width="240" left="4"/>
+ <button label="Carica valore predefinito" name="PrefLoadButton" width="145" left_pad="7"/>
min_val=&quot;0.125&quot;
- <button label="Elimina valore predefinito..." name="PrefDeleteButton"/>
+ <button label="Elimina valore predefinito" name="PrefDeleteButton" width="148" left_pad="7"/>
<button label="Ripristina impostazioni consigliate" name="Defaults"/>
<button label="Impostazioni avanzate..." name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
index aa3ff53f4a..c9d90539e1 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
<text name="Proxy Settings:">
Impostazioni proxy:
</text>
- <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy"/>
+ <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy" width="160"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_region_environment.xml b/indra/newview/skins/default/xui/it/panel_region_environment.xml
index d7d9658e26..467bcdb005 100644
--- a/indra/newview/skins/default/xui/it/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Ambiente" name="panel_env_info">
- <text name="water_settings_title">
- Seleziona le impostazioni del ciclo dell&apos;acqua e del cielo/giornata che vuoi che vedano tutti coloro che visitano la tua regione. Maggiori informazioni
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Usa valori predefiniti di Second Life" name="use_sl_default_settings"/>
- <radio_item label="Usa le impostazioni seguenti" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Impostazione Acqua
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Seleziona un valore predefinito-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Ciclo cielo / giornata
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Cielo fisso" name="my_sky_settings"/>
- <radio_item label="Ciclo giornata" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Seleziona un valore predefinito-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Seleziona un valore predefinito-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Applica" name="apply_btn"/>
- <button label="Annulla" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Usa impostazioni predefinite
+ </string>
+ <string name="str_label_use_region">
+ Usa impostazioni regione
+ </string>
+ <string name="str_altitude_desription">
+ Cielo [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ Non è stato selezionato alcun lotto. Le impostazioni ambientali sono disabilitate.
+ </string>
+ <string name="str_cross_region">
+ Le impostazioni ambientali non sono disponibili oltre i confini della regione.
+ </string>
+ <string name="str_legacy">
+ Le impostazioni ambientali non sono disponibili per questa regione.
+ </string>
+ <string name="str_disallowed">
+ Il gestore della proprietà immobiliare non permette di cambiare gli ambienti del lotto in questa regione.
+ </string>
+ <string name="str_too_small">
+ Il lotto deve essere di almeno 128 metri quadri per supportare un ambiente.
+ </string>
+ <string name="str_empty">
+ (vuoto)
+ </string>
+ <string name="str_region_env">
+ (ambiente regione)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Utilizza Inventario" name="btn_select_inventory"/>
+ <button label="Personalizza" name="btn_edit"/>
+ <check_box label="I proprietari del lotto possono ignorare l’ambiente" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Sconosciuto
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Trascina un’impostazione dall’Inventario a questa casella per selezionarla come cielo corrente."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Sconosciuto
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Trascina un’impostazione dall’Inventario a questa casella per selezionarla come cielo corrente."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Cielo [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Sconosciuto
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Trascina un’impostazione dall’Inventario a questa casella per selezionarla come cielo corrente."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Suolo
+ </text>
+ <line_editor name="edt_invname_ground">
+ Sconosciuto
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Trascina un’impostazione dall’Inventario a questa casella per selezionarla come suolo."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Acqua
+ </text>
+ <line_editor name="edt_invname_water">
+ Sconosciuto
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Trascina un’impostazione dall’Inventario a questa casella per selezionarla come acqua."/>
+ </panel>
+ <button label="Reimposta" name="btn_rst_altitudes" tool_tip="Reimposta alle altitudini predefinite"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/it/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..b2d27b93fc
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmosfera e illuminazione" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/it/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/it/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..e4dd5e00c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Nuvole" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/it/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..3142d1442a
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Densità" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Termine esponenziale Rayleigh:" name="rayleigh_exponential"/>
+ <slider label="Scala esponenziale Rayleigh:" name="rayleigh_exponential_scale"/>
+ <slider label="Termine lineare Rayleigh:" name="rayleigh_linear"/>
+ <slider label="Termine costante Rayleigh:" name="rayleigh_constant"/>
+ <slider label="Altitudine massima Rayleigh:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Termine esponenziale Mie:" name="mie_exponential"/>
+ <slider label="Scala esponenziale Mie:" name="mie_exponential_scale"/>
+ <slider label="Termine lineare Mie:" name="mie_linear"/>
+ <slider label="Termine costante Mie:" name="mie_constant"/>
+ <slider label="Fattore diverso Mie:" name="mie_aniso_factor"/>
+ <slider label="Altitudine massima Mie:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Termine esponenziale di assorbimento:" name="absorption_exponential"/>
+ <slider label="Scala esponenziale di assorbimento:" name="absorption_exponential_scale"/>
+ <slider label="Termine lineare di assorbimento:" name="absorption_linear"/>
+ <slider label="Termine costante di assorbimento:" name="absorption_constant"/>
+ <slider label="Altitudine massima di assorbimento:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/it/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..5a167b0aea
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Sole e Luna" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Mostra marcatore" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Mostra marcatore" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_settings_water.xml b/indra/newview/skins/default/xui/it/panel_settings_water.xml
new file mode 100644
index 0000000000..0d123a6249
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Acqua" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Spostamento Fresnel:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_tools_texture.xml b/indra/newview/skins/default/xui/it/panel_tools_texture.xml
index 46e2717647..5b4cb5868f 100644
--- a/indra/newview/skins/default/xui/it/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/it/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Texture" name="Texture">
- <panel.string name="string repeats per meter">
- Ripetizioni al metro
- </panel.string>
- <panel.string name="string repeats per face">
- Ripetizioni per faccia
- </panel.string>
<text name="color label">
Colore
</text>
@@ -114,4 +108,5 @@
<spinner label="Spostamento orizzontale" name="shinyOffsetU"/>
<spinner label="Spostamento verticale" name="shinyOffsetV"/>
<check_box initial_value="false" label="Allinea facce planari" name="checkbox planar align" tool_tip="Allinea le texture su tutte le facce selezionate con l’ultima faccia selezionata. È richiesta la mappatura planare delle texture."/>
+ <button label="Alllinea" label_selected="Alllinea livelli di texture attuali" name="button align textures" tool_tip="Alllinea livelli di texture attuali"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/role_actions.xml b/indra/newview/skins/default/xui/it/role_actions.xml
index 2bfaea8963..0e00165227 100644
--- a/indra/newview/skins/default/xui/it/role_actions.xml
+++ b/indra/newview/skins/default/xui/it/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Cambiare impostazioni musica e multimediali" longdescription="Cambia le impostazioni per lo streaming della musica e dei video in Informazioni sul terreno &gt; Media." name="land change media" value="20"/>
<action description="Attiva &apos;Modifica terreno&apos;" longdescription="Attiva &apos;Modifica terreno&apos;. *ATTENZIONE* Informazioni sul terreno &gt; Opzioni &gt; Modifica terreno consente a chiunque di modificare la forma del tuo terreno e di collocare e spostare le piante Linden. Pertanto sii sicuro della scelta prima di assegnare questa Abilità. La funzione di modifica del terreno è attivata in Informazioni sul terreno &gt; Opzioni." name="land edit" value="21"/>
<action description="Attivazione di parametri per Informazioni sul terreno &gt; Opzioni" longdescription="Premi Sicuro (nessun danno), Vola e consenti agli altri residenti di: modificare il terreno, costruire, creare punti di riferimento ed eseguire script nel terreno appartenente ad un gruppo in Informazioni sul terreno &gt; scheda Opzioni." name="land options" value="22"/>
+ <action description="Modifica le impostazioni dell’ambiente e del ciclo giornata." longdescription="Cambia le impostazioni dell’ambiente e del ciclo giornata dalla scheda Informazioni sul terreno &gt; Ambiente." name="land change environment" value="46"/>
</action_set>
<action_set description="Queste abilità permettono ai membri di non avere restrizioni in un lotto appartenente ad un gruppo." name="Parcel Powers">
<action description="Consenti sempre la modifica del terreno" longdescription="I membri con questo ruolo e abilità possono modificare il terreno appartenente ad un gruppo, anche se la funzionalità è disattivata in Informazioni sul terreno &gt; Opzioni." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 9265ce9ec6..f0466cea81 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -635,6 +635,15 @@ Prova ad accedere nuovamente tra un minuto.
<string name="BUTTON_HELP">
Mostra Aiuto
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Oggetti di questo tipo non possono essere allegati ai
+biglietti in questa regione.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Solamente gli oggetti con autorizzazioni
+illimitate al “proprietario successivoâ€
+possono essere allegati ai biglietti.
+ </string>
<string name="Searching">
Ricerca in corso...
</string>
@@ -711,6 +720,18 @@ Prova ad accedere nuovamente tra un minuto.
Errore nella richiesta di caricamento. Vai alla pagina
http://secondlife.com/support per risolvere il problema.
</string>
+ <string name="SettingValidationError">
+ Impossibile convalidare le impostazioni importate [NAME]
+ </string>
+ <string name="SettingImportFileError">
+ Impossibile aprire il file [FILE]
+ </string>
+ <string name="SettingParseFileError">
+ Impossibile aprire il file [FILE]
+ </string>
+ <string name="SettingTranslateError">
+ Impossibile tradurre la legacy vento e luce [NAME]
+ </string>
<string name="texture">
texture
</string>
@@ -786,6 +807,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="symbolic folder link">
link alla cartella
</string>
+ <string name="settings blob">
+ impostazioni
+ </string>
<string name="mesh">
reticolo
</string>
@@ -1116,6 +1140,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="ForceSitAvatar">
Forza l&apos;avatar a sedersi
</string>
+ <string name="ChangeEnvSettings">
+ Cambia le impostazioni dell’ambiente
+ </string>
<string name="AgentNameSubst">
(Tu)
</string>
@@ -1264,6 +1291,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="tattoo">
Tatuaggio
</string>
+ <string name="universal">
+ Universale
+ </string>
<string name="physics">
Fisica
</string>
@@ -1306,6 +1336,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="tattoo_not_worn">
Tatuaggio non portato
</string>
+ <string name="universal_not_worn">
+ Universale non indossato
+ </string>
<string name="physics_not_worn">
Fisica non indossata
</string>
@@ -1357,6 +1390,9 @@ http://secondlife.com/support per risolvere il problema.
<string name="create_new_tattoo">
Crea un nuovo tatuaggio
</string>
+ <string name="create_new_universal">
+ Crea nuovo universale
+ </string>
<string name="create_new_physics">
Crea nuova fisica
</string>
@@ -1600,11 +1636,14 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="MarketplaceUpdating">
in aggiornamento...
</string>
+ <string name="UploadFeeInfo">
+ Il costo si basa sul tuo livello di iscrizione. Più alto è il livello, più basso è il costo. [https://secondlife.com/my/account/membership.php? Scopri di più]
+ </string>
<string name="Open landmarks">
- Apri luoghi di riferimento
+ Luoghi aperti
</string>
<string name="Unconstrained">
- Libero
+ Senza limitazioni
</string>
<string name="no_transfer" value="(nessun trasferimento)"/>
<string name="no_modify" value="(nessuna modifica)"/>
@@ -2492,6 +2531,27 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="RegionSettings">
Impostazioni regione
</string>
+ <string name="NoEnvironmentSettings">
+ Questa regione non supporta le impostazioni per l’ambiente.
+ </string>
+ <string name="EnvironmentSun">
+ Sole
+ </string>
+ <string name="EnvironmentMoon">
+ Luna
+ </string>
+ <string name="EnvironmentBloom">
+ Fioritura
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Rumore nuvole
+ </string>
+ <string name="EnvironmentNormalMap">
+ Mappa normale
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparent
+ </string>
<string name="ClassifiedClicksTxt">
Clicca: [TELEPORT] teleport, [MAP] mappa, [PROFILE] profilo
</string>
@@ -4645,6 +4705,9 @@ Segnala abuso
<string name="New Tattoo">
Nuovo tatuaggio
</string>
+ <string name="New Universal">
+ Nuovo Universale
+ </string>
<string name="New Physics">
Nuova fisica
</string>
@@ -4771,6 +4834,15 @@ Segnala abuso
<string name="Female - Wow">
Femmina - Accipicchia
</string>
+ <string name="New Daycycle">
+ Nuovo ciclo giornata
+ </string>
+ <string name="New Water">
+ Nuova acqua
+ </string>
+ <string name="New Sky">
+ Nuovo cielo
+ </string>
<string name="/bow">
/inchino
</string>
@@ -4943,6 +5015,15 @@ Consulta la pagina http://status.secondlifegrid.net per determinare se il proble
<string name="Chat" value="Chat :">
Chat
</string>
+ <string name="BaseMembership">
+ Base
+ </string>
+ <string name="PremiumMembership">
+ Premium
+ </string>
+ <string name="Premium PlusMembership">
+ Premium Plus
+ </string>
<string name="DeleteItems">
Cancellare gli elementi selezionati?
</string>
@@ -5299,6 +5380,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="BeaconMedia">
Visualizzazione marcatori multimedia (bianco)
</string>
+ <string name="BeaconSun">
+ Marcatore visualizza direzione sole (arancione)
+ </string>
+ <string name="BeaconMoon">
+ Marcatore visualizza direzione luna (viola)
+ </string>
<string name="ParticleHiding">
Particelle nascoste
</string>
@@ -5326,6 +5413,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Command_Destinations_Label">
Destinazioni
</string>
+ <string name="Command_Environments_Label">
+ I miei ambienti
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5419,6 +5512,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Command_Destinations_Tooltip">
Destinazioni interessanti
</string>
+ <string name="Command_Environments_Tooltip">
+ I miei ambienti
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Pubblica su Facebook
+ </string>
<string name="Command_Flickr_Tooltip">
Carica su Flickr
</string>
@@ -5614,6 +5713,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="ExperiencePermission12">
accettazione automatica delle autorizzazioni per le esperienze
</string>
+ <string name="ExperiencePermission16">
+ obbliga l&apos;avatar a sedersi
+ </string>
+ <string name="ExperiencePermission17">
+ cambia le impostazioni dell’ambiente
+ </string>
<string name="ExperiencePermissionShortUnknown">
ha eseguito un&apos;operazione sconosciuta: [Permission]
</string>
@@ -5638,6 +5743,12 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="ExperiencePermissionShort12">
Autorizzazione
</string>
+ <string name="ExperiencePermissionShort16">
+ Siediti
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Ambiente
+ </string>
<string name="logging_calls_disabled_log_empty">
Le conversazioni non vengono registrate. Per iniziare a registrare, seleziona &quot;Salva: Solo registro&quot; oppure &quot;Salva: Registri e trascrizioni&quot; in Preferenze &gt; Chat.
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_about_land.xml b/indra/newview/skins/default/xui/ja/floater_about_land.xml
index d26a1b34d5..4703dfaa34 100644
--- a/indra/newview/skins/default/xui/ja/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml
@@ -478,5 +478,6 @@
</panel>
</panel>
<panel label="体験" name="land_experiences_panel"/>
+ <panel label="環境" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_adjust_environment.xml b/indra/newview/skins/default/xui/ja/floater_adjust_environment.xml
new file mode 100644
index 0000000000..6736dad336
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="個人的ãªç…§æ˜Ž">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="リセット" name="btn_reset" tool_tip="é–‰ã˜ã¦å…±æœ‰ã•れãŸç’°å¢ƒã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹"/>
+ <text name="cloud_map_label">
+ 雲ã®ç”»åƒï¼š
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ 太陽:
+ </text>
+ <check_box label="ビーコンを表示" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="ビーコンを表示" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_beacons.xml b/indra/newview/skins/default/xui/ja/floater_beacons.xml
index a55698e3d0..cb3dae0644 100644
--- a/indra/newview/skins/default/xui/ja/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/ja/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="音æº" name="sounds"/>
<check_box label="パーティクルæº" name="particles"/>
<check_box label="メディアæº" name="moapbeacon"/>
+ <check_box label="太陽" name="sun"/>
+ <check_box label="月" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml b/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
index b34fd192a9..fc9b35a34d 100644
--- a/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="サウンド"/>
<check_box label="テクスãƒãƒ£" name="check_texture"/>
<icon name="icon_texture" tool_tip="テクスãƒãƒ£"/>
+ <icon name="icon_setting" tool_tip="自然環境ã®è¨­å®š"/>
<button label="ã™ã¹ã¦ã« √" label_selected="å…¨ã¦" name="check_all"/>
<button label="クリア" label_selected="ãªã—" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
index a472f163e3..ac2db917cc 100644
--- a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="購入ã™ã‚‹" name="buy_btn"/>
<button label="å–り消ã—" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
購入ã§ãã¾ã›ã‚“
- </text>
- <button label="Web サイトã«ç§»å‹•" name="error_web" width="140"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml
deleted file mode 100644
index 6467a69956..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="環境ã®äº‹å‰è¨­å®šã‚’削除">
- <string name="title_water">
- æ°´ã®äº‹å‰è¨­å®šã‚’削除
- </string>
- <string name="title_sky">
- 空ã®äº‹å‰è¨­å®šã‚’削除
- </string>
- <string name="title_day_cycle">
- デイサイクルを削除
- </string>
- <string name="label_water">
- 事å‰è¨­å®šï¼š
- </string>
- <string name="label_sky">
- 事å‰è¨­å®šï¼š
- </string>
- <string name="label_day_cycle">
- デイサイクル:
- </string>
- <string name="msg_confirm_deletion">
- é¸æŠžã•れãŸäº‹å‰è¨­å®šã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
- </string>
- <string name="msg_sky_is_referenced">
- デイサイクルã®å‚ç…§å…ˆã¨ã—ã¦ä½¿ã‚れã¦ã„る事å‰è¨­å®šã¯å‰Šé™¤ã§ãã¾ã›ã‚“。
- </string>
- <string name="combo_label">
- - 事å‰è¨­å®šã‚’é¸æŠž -
- </string>
- <text name="label">
- 事å‰è¨­å®šï¼š
- </text>
- <button label="削除" name="delete"/>
- <button label="キャンセル" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..79c97472df
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="デイサイクルを編集">
+ <string name="title_new">
+ æ–°ã—ã„デイサイクルを作æˆ
+ </string>
+ <string name="title_edit">
+ デイサイクルを編集
+ </string>
+ <string name="hint_new">
+ æ–°ã—ã„デイサイクルã«åå‰ã‚’ã¤ã‘ã€å¸Œæœ›ã®è¨­å®šã«èª¿ç¯€ã—ã¦ã€ã€Œä¿å­˜ã€ã‚’クリックã—ã¾ã™ã€‚
+ </string>
+ <string name="hint_edit">
+ 自分ã§ä½œæˆã—ãŸãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã‚’編集ã™ã‚‹ã«ã¯ã€å¸Œæœ›ã®è¨­å®šã«èª¿ç¯€ã—ã¦ã€ã€Œä¿å­˜ã€ã‚’クリックã—ã¾ã™ã€‚
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ 空 [ALT]
+ </string>
+ <string name="sky_label">
+ 空
+ </string>
+ <string name="water_label">
+ æ°´
+ </string>
+ <string name="commit_parcel">
+ 区画ã«é©ç”¨
+ </string>
+ <string name="commit_region">
+ リージョンã«é©ç”¨
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ デイサイクルå:
+ </text>
+ <button label="インãƒãƒ¼ãƒˆ" name="btn_import" tool_tip="ディスクã‹ã‚‰éŽåŽ»ã®è¨­å®šã‚’インãƒãƒ¼ãƒˆã™ã‚‹ã€‚"/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="空 4" name="sky4_track"/>
+ <button label="空 3" name="sky3_track"/>
+ <button label="空 2" name="sky2_track"/>
+ <button label="地表レベル" name="sky1_track"/>
+ <button label="æ°´" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="トラックを以下ã‹ã‚‰ã‚¯ãƒ­ãƒ¼ãƒ³" name="copy_track"/>
+ <button label="トラックを以下ã‹ã‚‰ãƒ­ãƒ¼ãƒ‰" name="load_track"/>
+ <button label="トラックをクリア" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="後ã‚ã«ç§»å‹•"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="å‰ã«ç§»å‹•"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="[FRAME] を追加" name="add_frame"/>
+ <button label="[FRAME] をロード" name="btn_load_frame"/>
+ <button label="[FRAME] を削除" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ 上部ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã‹ã‚‰ã‚­ãƒ¼ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’é¸æŠžã—ã€è¨­å®šã‚’編集ã—ã¾ã™ã€‚
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="æ°´" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="大気&光" name="atmosphere_panel"/>
+ <panel label="雲" name="clouds_panel"/>
+ <panel label="太陽&月" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="ä¿å­˜" name="save_btn"/>
+ <button label="キャンセル" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/ja/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..a00b87b990
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="固定ã•れãŸç’°å¢ƒ">
+ <string name="edit_sky">
+ 空を編集:
+ </string>
+ <string name="edit_water">
+ 水を編集:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="ロード" name="btn_load" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ロードã™ã‚‹"/>
+ <button label="インãƒãƒ¼ãƒˆ" name="btn_import" tool_tip="ディスクã‹ã‚‰éŽåŽ»ã®è¨­å®šã‚’インãƒãƒ¼ãƒˆã™ã‚‹ã€‚"/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="ä¿å­˜" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="キャンセル" name="btn_cancel" tool_tip="最後ã«ä¿å­˜ã•れãŸçŠ¶æ…‹ã«æˆ»ã™"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
index da63b54eab..425cb7ad81 100644
--- a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
@@ -12,6 +12,7 @@
<check_box label="サウンド" name="check_sound"/>
<check_box label="テクスãƒãƒ£" name="check_texture"/>
<check_box label="スナップショット" name="check_snapshot"/>
+ <check_box label="設定" name="check_settings"/>
<button label="ã™ã¹ã¦" label_selected="ã™ã¹ã¦" name="All"/>
<button label="ãªã—" label_selected="ãªã—" name="None"/>
<check_box label="常ã«ãƒ•ォルダを表示" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
deleted file mode 100644
index 2edb3c624c..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹">
- <string name="OutboxFolderCount1">
- 1 個ã®ãƒ•ォルダ
- </string>
- <string name="OutboxFolderCountN">
- [NUM] 個ã®ãƒ•ォルダ
- </string>
- <string name="OutboxImporting">
- フォルダをé€ä¿¡ä¸­...
- </string>
- <string name="OutboxInitializing">
- åˆæœŸåŒ–中...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- ロード中...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- ã“ã“ã«ã‚¢ã‚¤ãƒ†ãƒ ã‚’ドラッグã—ã¦ã€ãƒ•ォルダを作æˆã™ã‚‹
- </text>
- </panel>
- <button label="マーケットプレイスã«é€ä¿¡" name="outbox_import_btn" tool_tip="自分ã®ãƒžãƒ¼ã‚±ãƒƒãƒˆãƒ—レイス店頭ã«ç§»å‹•"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_my_environments.xml b/indra/newview/skins/default/xui/ja/floater_my_environments.xml
new file mode 100644
index 0000000000..d697a9f321
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="場所" name="my_environments" title="ç§ã®ç’°å¢ƒ">
+ <layout_stack>
+ <layout_panel label="フィルター" name="filter_panel">
+ <check_box label="日間" name="chk_days"/>
+ <check_box label="空" name="chk_skies"/>
+ <check_box label="æ°´" name="chk_water"/>
+ <filter_editor label="環境ã®çµžã‚Šè¾¼ã¿" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="環境" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="ã™ã¹ã¦ã®ãƒ•ォルダを表示" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="ãã®ä»–ã®ã‚ªãƒ—ションを表示"/>
+ <menu_button name="btn_newsettings" tool_tip="æ–°è¦è¨­å®šã‚’作æˆ"/>
+ <button name="btn_del" tool_tip="é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’削除"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_perms_default.xml b/indra/newview/skins/default/xui/ja/floater_perms_default.xml
index 0dfc75014e..33551a5706 100644
--- a/indra/newview/skins/default/xui/ja/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/ja/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="è¡£æœã¾ãŸã¯ãƒœãƒ‡ã‚£ãƒ‘ーツを作æˆã™ã‚‹ã¨ãã«ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã‚’設定ã™ã‚‹">
ç€ç”¨ç‰©
</text>
+ <text name="label_13" tool_tip="自然環境ã®è¨­å®šã‚’作æˆã™ã‚‹ã¨ãã«ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã‚’設定ã™ã‚‹">
+ 設定
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="å–り消ã—" label_selected="å–り消ã—" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_pick_track.xml b/indra/newview/skins/default/xui/ja/floater_pick_track.xml
new file mode 100644
index 0000000000..e5773e1ec8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="é¸æŠžï¼šãƒˆãƒ©ãƒƒã‚¯">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ 空ã®ã‚½ãƒ¼ã‚¹ã‚’é¸æŠžï¼š
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="空 4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="空 3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="空 2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="地é¢" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="キャンセル" label_selected="キャンセル" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
index c28afa4c98..8ba537faa2 100644
--- a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="逿˜Žãªæ°´" name="TransparentWater"/>
<check_box initial_value="true" label="ãƒãƒ³ãƒ—マッピングã¨å…‰æ²¢" name="BumpShiny"/>
<check_box initial_value="true" label="è¿‘ãã®å…‰" name="LocalLights"/>
- <check_box initial_value="true" label="基本シェーダー" name="BasicShaders" tool_tip="ã“ã®ã‚ªãƒ—ションを無効ã«ã™ã‚‹ã¨ã€ã‚°ãƒ©ãƒ•ィックカードã®ãƒ‰ãƒ©ã‚¤ãƒã®ç¨®é¡žã«ã‚ˆã£ã¦ã¯ã€ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã™ã‚‹ã®ã‚’防ãŽã¾ã™ã€‚"/>
<slider label="地形詳細:" name="TerrainDetail"/>
<text name="TerrainDetailText">
低
diff --git a/indra/newview/skins/default/xui/ja/floater_settings_picker.xml b/indra/newview/skins/default/xui/ja/floater_settings_picker.xml
new file mode 100644
index 0000000000..b8b1699f03
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="é¸æŠžï¼šè¨­å®š">
+ <floater.string name="pick title">
+ é¸æŠžï¼š
+ </floater.string>
+ <floater.string name="pick_track">
+ ãƒˆãƒ©ãƒƒã‚¯ã‚’é¸æŠž
+ </floater.string>
+ <floater.string name="pick_settings">
+ è¨­å®šã‚’é¸æŠž
+ </floater.string>
+ <floater.string name="track_water">
+ æ°´
+ </floater.string>
+ <floater.string name="track_ground">
+ 地é¢
+ </floater.string>
+ <floater.string name="track_sky">
+ 空 [NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="テクスãƒãƒ£ã‚’フィルター" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="キャンセル" label_selected="キャンセル" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
index 37233d3e68..1221702e9b 100644
--- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
@@ -9,18 +9,14 @@
<text name="Multiple">
複数ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£
</text>
- <radio_group name="mode_selection">
- <radio_item label="インベントリ" name="inventory" value="0"/>
- <radio_item label="ローカル" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- サイズ: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="インベントリ" name="inventory" value="0"/>
+ <combo_box.item label="ローカル" name="local" value="1"/>
+ </combo_box>
<button label="デフォルト" label_selected="デフォルト" name="Default"/>
<button label="ブランク" label_selected="ブランク" name="Blank"/>
<button label="ãªã—" label_selected="ãªã—" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <check_box initial_value="true" label="今ã™ãé©ç”¨" name="apply_immediate_check"/>
<text name="preview_disabled" value="プレビュー無効"/>
<filter_editor label="テクスãƒãƒ£ã‚’フィルター" name="inventory search editor"/>
<check_box initial_value="false" label="フォルダを表示" name="show_folders_check"/>
@@ -31,6 +27,22 @@
<column label="åå‰" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="構築(ベーク)ã™ã‚‹ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’é¸æŠž">
+ <combo_box.item label="ãªã—" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="基本ã¨ãªã‚‹ãƒ¡ãƒƒã‚·ãƒ¥ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã‚’éš ã™" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel"/>
+ <check_box initial_value="true" label="今ã™ãé©ç”¨" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
index e786d02e40..aa07b9476e 100644
--- a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="触る" name="touch_attach" />
+ <menu_item_call label="編集" name="edit_item" />
<menu_item_call label="å–り外ã™" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml
index 0b06b77901..7f68c18e0b 100644
--- a/indra/newview/skins/default/xui/ja/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="有効ã«ã™ã‚‹" name="Marketplace Activate"/>
<menu_item_call label="無効ã«ã™ã‚‹" name="Marketplace Deactivate"/>
<menu_item_call label="共有" name="Share"/>
- <menu_item_call label="購入" name="Task Buy"/>
<menu_item_call label="é–‹ã" name="Task Open"/>
<menu_item_call label="å†ç”Ÿ" name="Task Play"/>
<menu_item_call label="プロパティ" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="æ–°ã—ã„パンツ" name="New Underpants"/>
<menu_item_call label="æ–°ã—ã„アルファマスク" name="New Alpha Mask"/>
<menu_item_call label="æ–°ã—ã„タトゥ" name="New Tattoo"/>
+ <menu_item_call label="æ–°ã—ã„ユニãƒãƒ¼ã‚µãƒ«" name="New Universal"/>
<menu_item_call label="æ–°è¦ã®ç‰©ç†ä½œç”¨" name="New Physics"/>
</menu>
<menu label="æ–°ã—ã„身体部ä½" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="æ–°ã—ã„髪" name="New Hair"/>
<menu_item_call label="æ–°ã—ã„眼" name="New Eyes"/>
</menu>
+ <menu label="æ–°ã—ã„設定" name="New Settings">
+ <menu_item_call label="æ–°ã—ã„空" name="New Sky"/>
+ <menu_item_call label="æ–°ã—ã„æ°´" name="New Water"/>
+ <menu_item_call label="æ–°ã—ã„デイサイクル" name="New Day Cycle"/>
+ </menu>
<menu label="次ã®ãƒ‡ãƒ•ォルトã¨ã—ã¦ä½¿ç”¨" name="upload_def">
<menu_item_call label="ç”»åƒã®ã‚¢ãƒƒãƒ—ロード" name="Image uploads"/>
<menu_item_call label="サウンドã®ã‚¢ãƒƒãƒ—ロード" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="装ç€" name="Wearable And Object Wear"/>
<menu label="装ç€å…ˆ" name="Attach To"/>
<menu label="HUD 装ç€å…ˆ" name="Attach To HUD"/>
+ <menu_item_call label="触る" name="Attachment Touch" />
<menu_item_call label="編集" name="Wearable Edit"/>
<menu_item_call label="追加" name="Wearable Add"/>
<menu_item_call label="å–り外ã™" name="Take Off"/>
+ <menu_item_call label="自分ã«ã®ã¿é©ç”¨" name="Settings Apply Local"/>
+ <menu_item_call label="区画ã«é©ç”¨" name="Settings Apply Parcel"/>
<menu_item_call label="マーケットプレイスã®ãƒªã‚¹ãƒˆã«ã‚³ãƒ”ー" name="Marketplace Copy"/>
<menu_item_call label="マーケットプレイスã®ãƒªã‚¹ãƒˆã«ç§»å‹•" name="Marketplace Move"/>
<menu_item_call label="ï¼ï¼ã‚ªãƒ—ションãªã—ï¼ï¼" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory_add.xml b/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
index ae5ddbb78f..eecf166a70 100644
--- a/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="サウンド (L$[COST] )..." name="Upload Sound"/>
<menu_item_call label="アニメーション (L$ [COST] )..." name="Upload Animation"/>
<menu_item_call label="モデル" name="Upload Model"/>
- <menu_item_call label="モデルウィザード" name="Upload Model Wizard"/>
<menu_item_call label="一括 (ファイルã«ã¤ã L$[COST] )..." name="Bulk Upload"/>
- <menu_item_call label="デフォルトã®ã‚¢ãƒƒãƒ—ロード権é™ã‚’設定" name="perm prefs"/>
</menu>
<menu_item_call label="æ–°è¦ãƒ•ォルダ" name="New Folder"/>
<menu_item_call label="æ–°è¦ã‚¹ã‚¯ãƒªãƒ—ト" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="æ–°ã—ã„下ç€ï¼ˆä¸‹ï¼‰" name="New Underpants"/>
<menu_item_call label="æ–°ã—ã„アルファ" name="New Alpha"/>
<menu_item_call label="æ–°ã—ã„タトゥー" name="New Tattoo"/>
+ <menu_item_call label="æ–°ã—ã„ユニãƒãƒ¼ã‚µãƒ«" name="New Universal"/>
<menu_item_call label="æ–°è¦ã®ç‰©ç†ä½œç”¨" name="New Physics"/>
</menu>
<menu label="æ–°ã—ã„身体部ä½" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="æ–°ã—ã„髪" name="New Hair"/>
<menu_item_call label="æ–°ã—ã„ç›®" name="New Eyes"/>
</menu>
+ <menu label="æ–°ã—ã„設定" name="New Settings">
+ <menu_item_call label="æ–°ã—ã„空" name="New Sky"/>
+ <menu_item_call label="æ–°ã—ã„æ°´" name="New Water"/>
+ <menu_item_call label="æ–°ã—ã„デイサイクル" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
index 5e02fd3b8f..4946d58fd8 100644
--- a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="アルファ" name="New Alpha"/>
<menu_item_call label="æ–°è¦ã®ç‰©ç†ä½œç”¨" name="New Physics"/>
<menu_item_call label="æ–°ã—ã„タトゥ" name="New Tattoo"/>
+ <menu_item_call label="æ–°ã—ã„ユニãƒãƒ¼ã‚µãƒ«" name="New Universal"/>
</menu>
<menu label="æ–°ã—ã„身体部ä½" name="New Body Parts">
<menu_item_call label="æ–°ã—ã„シェイプ" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_save_settings.xml b/indra/newview/skins/default/xui/ja/menu_save_settings.xml
new file mode 100644
index 0000000000..44fb1fb30b
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="ä¿å­˜" name="save_settings"/>
+ <menu_item_check label="別åã§ä¿å­˜" name="save_as_new_settings"/>
+ <menu_item_check label="ç´„æŸã™ã‚‹" name="commit_changes"/>
+ <menu_item_check label="自分ã«ã®ã¿é©ç”¨" name="apply_local"/>
+ <menu_item_check label="区画ã«é©ç”¨" name="apply_parcel"/>
+ <menu_item_check label="リージョンã«é©ç”¨" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_settings_add.xml b/indra/newview/skins/default/xui/ja/menu_settings_add.xml
new file mode 100644
index 0000000000..814ad9c1a6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="æ–°ã—ã„空" name="New Sky"/>
+ <menu_item_call label="æ–°ã—ã„æ°´" name="New Water"/>
+ <menu_item_call label="æ–°ã—ã„デイサイクル" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_settings_gear.xml b/indra/newview/skins/default/xui/ja/menu_settings_gear.xml
new file mode 100644
index 0000000000..064eae95bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="編集" name="edit_settings"/>
+ <menu_item_call label="自分ã«ã®ã¿é©ç”¨" name="Settings Apply Local"/>
+ <menu_item_call label="区画ã«é©ç”¨" name="Settings Apply Parcel"/>
+ <menu_item_call label="リージョンã«é©ç”¨" name="Settings Apply Region"/>
+ <menu_item_call label="コピー" name="copy_settings"/>
+ <menu_item_call label="貼り付ã‘" name="paste_settings"/>
+ <menu_item_call label="UUID をコピー" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 7810094823..ba8d8e4955 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="区画プロパティ" name="Parcel Properties"/>
<menu_item_check label="アドãƒãƒ³ã‚¹ãƒ¡ãƒ‹ãƒ¥ãƒ¼" name="Show Advanced Menu"/>
</menu>
- <menu label="æ—¥" name="Sun">
+ <menu label="環境" name="Environment">
<menu_item_check label="æ—¥ã®å‡º" name="Sunrise"/>
<menu_item_check label="æ­£åˆ" name="Noon"/>
<menu_item_check label="日没" name="Sunset"/>
<menu_item_check label="深夜" name="Midnight"/>
- <menu_item_check label="リージョンã®è¨­å®šã‚’使用" name="Use Region Settings"/>
- </menu>
- <menu label="自然環境エディター" name="Environment Editor">
- <menu_item_call label="自然環境ã®è¨­å®š..." name="Environment Settings"/>
- <menu label="æ°´ã®äº‹å‰è¨­å®š" name="Water Presets">
- <menu_item_call label="æ–°ã—ã„事å‰è¨­å®š..." name="new_water_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’編集..." name="edit_water_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’削除..." name="delete_water_preset"/>
- </menu>
- <menu label="空ã®äº‹å‰è¨­å®š" name="Sky Presets">
- <menu_item_call label="æ–°ã—ã„事å‰è¨­å®š..." name="new_sky_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’編集..." name="edit_sky_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’削除..." name="delete_sky_preset"/>
- </menu>
- <menu label="デイã®äº‹å‰è¨­å®š" name="Day Presets">
- <menu_item_call label="æ–°ã—ã„事å‰è¨­å®š..." name="new_day_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’編集..." name="edit_day_preset"/>
- <menu_item_call label="事å‰è¨­å®šã‚’削除..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="共有ã•れãŸç’°å¢ƒã‚’使用" name="Use Shared Environment"/>
+ <menu_item_call label="ç§ã®ç’°å¢ƒâ€¦" name="my_environs"/>
+ <menu_item_call label="個人的ãªç…§æ˜Žâ€¦" name="adjustment_tool"/>
+ <menu_item_check label="é›²ã‚’ä¸€æ™‚åœæ­¢" name="pause_clouds"/>
</menu>
</menu>
<menu label="制作" name="BuildTools">
@@ -346,6 +331,9 @@
<menu_item_check label="自動アルファマスク(é…å»¶ãªã—)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="アニメーションテクスãƒãƒ£" name="Animation Textures"/>
<menu_item_check label="テクスãƒãƒ£ã‚’無効ã«ã™ã‚‹" name="Disable Textures"/>
+ <menu_item_check label="アンビエントを無効ã«ã™ã‚‹" name="Disable Ambient"/>
+ <menu_item_check label="æ—¥ã®å‡ºã‚’無効ã«ã™ã‚‹" name="Disable Sunlight"/>
+ <menu_item_check label="è¿‘ãã®å…‰ã‚’無効ã«ã™ã‚‹" name="Disable Local Lights"/>
<menu_item_check label="フル解åƒåº¦ãƒ†ã‚¯ã‚¹ãƒãƒ£" name="Rull Res Textures"/>
<menu_item_check label="装ç€ã•れãŸå…‰æºã‚’æç”»ã™ã‚‹" name="Render Attached Lights"/>
<menu_item_check label="å–り付ã‘られãŸãƒ‘ーティクルをæç”»ã™ã‚‹" name="Render Attached Particles"/>
@@ -483,6 +471,7 @@
<menu_item_call label="スカート" name="Skirt"/>
<menu_item_call label="アルファ" name="Alpha"/>
<menu_item_call label="タトゥ" name="Tattoo"/>
+ <menu_item_call label="ユニãƒãƒ¼ã‚µãƒ«" name="Universal"/>
<menu_item_call label="物ç†ä½œç”¨" name="Physics"/>
<menu_item_call label="ã™ã¹ã¦ã®è¡£é¡ž" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
index c402fa0b6d..02029230ba 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="交æ›" name="wear_replace"/>
<menu_item_call label="装ç€" name="wear_wear"/>
<menu_item_call label="追加" name="wear_add"/>
+ <menu_item_call label="触る" name="touch" />
<menu_item_call label="å–り外ã™" name="take_off_or_detach"/>
<menu_item_call label="å–り外ã™" name="detach"/>
<context_menu label="装ç€ï¼š" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
index 5334042dc9..48aac2ed05 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="アウトフットã®ç·¨é›†" name="edit"/>
+ <menu_item_call label="触る" name="touch"/>
+ <menu_item_call label="編集" name="edit_item"/>
+ <menu_item_call label="アウトフットã®ç·¨é›†" name="edit_outfit"/>
<menu_item_call label="å–り外ã™" name="takeoff"/>
<menu_item_call label="アウトフィットã®ãƒªã‚¹ãƒˆã‚’クリップボードã«ã‚³ãƒ”ー" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
index bf8e72e457..8c331bc008 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="触る" name="touch_attach"/>
<menu_item_call label="å–り外ã™" name="take_off"/>
<menu_item_call label="å–り外ã™" name="detach"/>
- <menu_item_call label="アウトフットã®ç·¨é›†" name="edit"/>
+ <menu_item_call label="アウトフットã®ç·¨é›†" name="edit_outfit"/>
<menu_item_call label="編集" name="edit_item"/>
<menu_item_call label="オリジナルを表示" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 16aeb4dcd7..a66552d3fe 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -266,6 +266,10 @@
é¸æŠžã—ãŸä½äººã‹ã‚‰å¤‰æ›´æ¨©é™ã‚’å–り下ã’ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ グループå㯠[MIN_LEN] ~ [MAX_LEN] 文字ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
グループを作æˆã§ãã¾ã›ã‚“。
[MESSAGE]
@@ -367,7 +371,7 @@
L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
</notification>
<notification name="CreateGroupCost">
- ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—を作るã«ã¯ L$ 100 ã‹ã‹ã‚Šã¾ã™ã€‚
+ ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—作æˆã«ã‹ã‹ã‚‹è²»ç”¨ï¼šL$[COST]
一人ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã«ãªã‚‰ãªã„ã®ã§ã€æ°¸ä¹…ã«å‰Šé™¤ã•れã¦ã—ã¾ã„ã¾ã™ã€‚
48 時間以内ã«ãƒ¡ãƒ³ãƒãƒ¼ã‚’勧誘ã—ã€å…¥ä¼šã—ã¦ã‚‚らã£ã¦ãã ã•ã„。
<usetemplate canceltext="キャンセル" name="okcancelbuttons" notext="キャンセル" yestext="L$100 ã§ã‚°ãƒ«ãƒ¼ãƒ—を作æˆ"/>
@@ -518,6 +522,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
<notification name="ErrorEncodingSnapshot">
スナップショットã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰åŒ–ã§ã‚¨ãƒ©ãƒ¼ãŒå‡ºã¾ã—ãŸï¼
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’アップロードã™ã‚‹ãŸã‚ã«ã¯ L$[COST] ãŒå¿…è¦ã§ã™ã€‚
+ </notification>
<notification name="ErrorPhotoCannotAfford">
インベントリã«å†™çœŸã‚’ä¿å­˜ã™ã‚‹ã«ã¯ L$[COST] ãŒå¿…è¦ã§ã™ã€‚L$ を購入ã™ã‚‹ã‹ã€ä»£ã‚りã«å†™çœŸã‚’ã£ã‚³ãƒ³ãƒ”ュータã«ä¿å­˜ã§ãã¾ã™ã€‚
</notification>
@@ -1773,11 +1780,14 @@ https://secondlife.com/support/downloads/ ã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¦ãã ã
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- ベースアカウントã®ã‚°ãƒ«ãƒ¼ãƒ—制é™ã¯ [MAX_BASIC]ã€[https://secondlife.com/premium/ プレミアム] アカウントã®
-グループ制é™ã¯ [MAX_PREMIUM] ã§ã™ã€‚
-アカウントをダウングレードã—ãŸå ´åˆã€ã•らã«ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹å‰ã«ã€ä¸‹ã® [MAX_BASIC] グループ制é™ã‚’å–å¾—ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚
-
-[https://secondlife.com/my/account/membership.php 今ã™ãアップグレード!]
+ ベーシック会員ã®ä½æ°‘ã¯ã€æœ€å¤§ [MAX_BASIC] グループã¾ã§å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+プレミアム会員ã¯ã€æœ€å¤§ [MAX_PREMIUM] ã¾ã§å¯èƒ½ã§ã™ã€‚[https://secondlife.com/my/account/membership.php? 詳細ã€ã¾ãŸã¯ã‚¢ãƒƒãƒ—グレード]
+ <usetemplate name="okbutton" yestext="é–‰ã˜ã‚‹"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ ベーシック会員ã®ä½æ°‘ã¯ã€æœ€å¤§ [MAX_BASIC] グループã¾ã§å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+プレミアム会員ã¯ã€æœ€å¤§ [MAX_PREMIUM] ã¾ã§å¯èƒ½ã§ã™ã€‚プレミアムプラス会員ã¯ã€æœ€å¤§ [MAX_PREMIUM_PLUS] ã¾ã§å¯èƒ½ã§ã™ã€‚
+[https://secondlife.com/my/account/membership.php? 詳細ã€ã¾ãŸã¯ã‚¢ãƒƒãƒ—グレード]
<usetemplate name="okbutton" yestext="é–‰ã˜ã‚‹"/>
</notification>
<notification name="KickUser">
@@ -1996,6 +2006,11 @@ http://wiki.secondlife.com/wiki/Setting_your_display_name ã‚’å‚ç…§ã—ã¦ãã ã
ã“ã®ã‚ªãƒ—ションをオフã«ã™ã‚‹ã¨ã€å«ŒãŒã‚‰ã›ã®é˜²æ­¢ã‚„プライãƒã‚·ãƒ¼ã®ç¶­æŒã€18 æ‰ä»¥ä¸‹ã®ä½äººã‚’ Adult コンテンツã‹ã‚‰å®ˆã‚‹ãŸã‚ã«åŒºç”»æ‰€æœ‰è€…ãŒåŠ ãˆãŸåˆ¶é™ãŒè§£é™¤ã•れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚å¿…è¦ã«å¿œã˜ã¦åŒºç”»æ‰€æœ‰è€…ã¨ç›¸è«‡ã—ã¦ãã ã•ã„。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ ã“ã®ã‚ªãƒ—ションをオフã«ã™ã‚‹ã¨ã€åŒºç”»æ‰€æœ‰è€…ãŒãã®åŒºç”»ã«åŠ ãˆãŸã‚«ã‚¹ã‚¿ãƒ ç’°å¢ƒãŒå‰Šé™¤ã•れã¾ã™ã€‚å¿…è¦ã«å¿œã˜ã¦åŒºç”»æ‰€æœ‰è€…ã¨ç›¸è«‡ã—ã¦ãã ã•ã„。
+ç¶šã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’è¶…ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
@@ -2483,7 +2498,14 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
ã“ã®ãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ¬¡ã®å­˜åœ¨ã—ãªã„「空ã€ãƒ•ァイルをå‚ç…§ã—ã¦ã„ã¾ã™ï¼š [SKY]。
</notification>
<notification name="WLRegionApplyFail">
- 申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€è¨­å®šã‚’リージョンã«é©ç”¨ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚一度リージョンを出ã¦ã‹ã‚‰æˆ»ã‚‹ã¨ã€å•題ãŒè§£æ±ºã•れるã‹ã‚‚ã—れã¾ã›ã‚“。å•題ã®ç™ºç”Ÿã—ãŸç†ç”±ï¼š[FAIL_REASON]
+ 申ã—訳ã”ã–ã„ã¾ã›ã‚“ãŒã€è¨­å®šã‚’リージョンã«é©ç”¨ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ç†ç”±ï¼š [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ ローカルテクスãƒãƒ£ã¯ã€ãƒ•ィールド [FIELD] 内ã®ãƒˆãƒ©ãƒƒã‚¯ [TRACK]ã€ãƒ•レーム #[FRAMENO] ([FRAME]%) ã§ä½¿ç”¨ã•れã¦ã„ã¾ã™ã€‚ローカルテクスãƒãƒ£ã‚’使ã£ãŸè¨­å®šã¯ä¿å­˜ã•れãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ ローカルテクスãƒãƒ£ã¯ã€ãƒ•ィールド [FIELD] ã§ä½¿ç”¨ã•れã¦ã„ã¾ã™ã€‚
+ローカルテクスãƒãƒ£ã‚’使ã£ãŸè¨­å®šã¯ä¿å­˜ã•れãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
デイサイクルを空ã«ã¯ã§ããªã„ã®ã§ã€ã“ã®ãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã®æœ€å¾Œã®ã‚­ãƒ¼ã‚’削除ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。最後ã®ã‚­ãƒ¼ã‚’削除ã—ã¦æ–°ã—ã„キーを作æˆã™ã‚‹ã®ã§ã¯ãªãã€æœ€å¾Œã®ã‚­ãƒ¼ã‚’変更ã—ã¦ãã ã•ã„。
@@ -3337,6 +3359,22 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
モデレーターãŒã‚ãªãŸã®ãƒœã‚¤ã‚¹ã‚’ミュートã—ã¾ã—ãŸã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ 残念ãªãŒã‚‰ã€ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ãƒ™ãƒãƒ•ィット情報を得るã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚通常ã®ãƒ—ロダクション環境ã§èµ·ã“ã‚‹ã“ã¨ã§ã¯ã‚りã¾ã›ã‚“。サãƒãƒ¼ãƒˆã¾ã§ã”連絡ãã ã•ã„。ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã¯é€šå¸¸é€šã‚Šã«ä½œå‹•ã—ã¾ã›ã‚“ã®ã§ã€å†ã‚¹ã‚¿ãƒ¼ãƒˆã‚’ãŠè–¦ã‚ã—ã¾ã™
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ åˆè¨ˆ L$[COST] ã§ [COUNT] アイテムãŒã‚¢ãƒƒãƒ—ロードã•れã¾ã™ã€‚ アップロードを続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="アップロード"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ é¸æŠžã—ãŸãƒ•ァイルã¯ã€ã¾ã¨ã‚ã¦ã‚¢ãƒƒãƒ—ロードã§ãã¾ã›ã‚“。
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ é¸æŠžã—ãŸãƒ•ァイルã®ã„ãã¤ã‹ã¯ã€ã¾ã¨ã‚ã¦ã‚¢ãƒƒãƒ—ロードã§ãã¾ã›ã‚“。
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
ã“ã®ã‚¢ãƒƒãƒ—ロード㯠L$[PRICE] ã®ã‚³ã‚¹ãƒˆãŒã‹ã‹ã‚Šã¾ã™ã€‚アップロードを続ã‘ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="アップロード"/>
@@ -4429,4 +4467,75 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ データベースã‹ã‚‰ [NAME] ã®è¨­å®šã®èª­ã¿è¾¼ã¿ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ 環境ã«ã“れらã®è¨­å®šã‚’é©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ 環境ã«ã“れらã®è¨­å®šã‚’é©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¯ç’°å¢ƒè¨­å®šã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+ </notification>
+ <notification label="アウトフィットをä¿å­˜ã™ã‚‹" name="SaveSettingAs">
+ ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’次ã®å†…容ã§ä¿å­˜ã™ã‚‹ï¼š
+ <form name="form">
+ <input name="message">
+ [DESC] (新)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="キャンセル"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ [FILE] ã‹ã‚‰éŽåŽ»ã®ã‚¦ã‚¤ãƒ³ãƒ‰ãƒ©ã‚¤ãƒˆã®è¨­å®š [NAME] をインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“。
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ ã“ã®åŒºç”»ã§ç’°å¢ƒã‚’設定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+変更ã™ã‚‹æ¨©é™ã®ã‚る区画を入力ã¾ãŸã¯é¸æŠžã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="SettingsUnsuported">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯è¨­å®šã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+設定ã«å¯¾å¿œã—ã¦ã„るリージョンã«ç§»å‹•ã—ã€ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’å†è©¦è¡Œã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ &quot;[NAME]&quot;ã¨å付ã‘られãŸã“ã® [TYPE] ã«åŠ ãˆã‚‰ã‚ŒãŸå¤‰æ›´ãŒå¤±ã‚れã¾ã™ã€‚
+ç¶šã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="変更を失ã„ã¾ã™ãŒã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ é©ç”¨ã•れãŸã™ã¹ã¦ã®è¨­å®šã‚’削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚
+ç¶šã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ é©ç”¨ã•れãŸã™ã¹ã¦ã®å€‹äººçš„ãªç…§æ˜Žã®è¨­å®šã‚’削除ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚
+ç¶šã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ ã“ã®ãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã«ç§»è¡Œä¸å¯ã®è¨­å®šã‚’インãƒãƒ¼ãƒˆã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®ã¾ã¾ç¶šã‘ã‚‹ã¨ã€ç·¨é›†ä¸­ã®è¨­å®šã‚‚移行ä¸å¯ã«ãªã‚Šã¾ã™ã€‚
+
+ã“ã®å¤‰æ›´ã¯å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“。
+
+ç¶šã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="設定を移行ä¸å¯ã«ã—ã¾ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ ライブラリã‹ã‚‰ç›´æŽ¥è¨­å®šã‚’変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+è‡ªåˆ†ã®æŒã¡ç‰©ã‹ã‚‰ã‚³ãƒ”ーã—ã¦ã‚„り直ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ ã“ã®è¨­å®šã§å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã“ã®è¨­å®šã¯ç¾åœ¨ä¿å­˜ã¾ãŸã¯é©ç”¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="TrackLoadFailed">
+ トラックを [TRACK] ã«ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="TrackLoadMismatch">
+ トラックを [TRACK1] ã‹ã‚‰ [TRACK2] ã«ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“。
+ </notification>
</notifications>
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 b556b68e02..cf5f2489f1 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
@@ -47,7 +47,7 @@
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
<layout_panel name="show_on_map_btn_lp">
- <button label="å–り消ã—" name="cancel_btn"/>
+ <button label="キャンセル" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
index f4cfe6d83f..5729cb7552 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="頭部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Head Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠž"/>
- <texture_picker label="上部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Upper Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠž"/>
- <texture_picker label="下部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Lower Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠž"/>
- <color_swatch label="色・色彩é…åˆ" name="Color/Tint" tool_tip="クリックã—ã¦ã‚«ãƒ©ãƒ¼ãƒ”ッカーを開ãã¾ã™"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="頭部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Head Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="上部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Upper Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="下部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Lower Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <color_swatch label="è‰²ï¼æ˜Žæš—" name="Color/Tint" tool_tip="クリックã—ã¦ã‚«ãƒ©ãƒ¼ãƒ”ッカーを開ãã¾ã™"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_universal.xml b/indra/newview/skins/default/xui/ja/panel_edit_universal.xml
new file mode 100644
index 0000000000..614fd1059f
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="頭部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Head Universal Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="上部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Upper Universal Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="下部ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Lower Universal Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="スカートã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Skirt Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="é«ªã®æ¯›ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Hair Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="ç›®ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Eyes Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="左腕ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Left Arm Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="左脚ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Left Leg Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="Aux1 ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Aux1 Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="Aux2 ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Aux2 Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <texture_picker label="Aux3 ã®ã‚¿ãƒˆã‚¥ãƒ¼" name="Aux3 Tattoo" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã™ã‚‹"/>
+ <color_swatch label="è‰²ï¼æ˜Žæš—" name="Color/Tint" tool_tip="クリックã—ã¦ã‚«ãƒ©ãƒ¼ãƒ”ッカーを開ãã¾ã™"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
index 000dac7b5b..9101920f1b 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
タトゥーを編集中
</string>
+ <string name="edit_universal_title">
+ ユニãƒãƒ¼ã‚µãƒ«ã‚’編集中
+ </string>
<string name="edit_physics_title">
物ç†ä½œç”¨ã®ç·¨é›†ä¸­
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
タトゥ:
</string>
+ <string name="universal_desc_text">
+ ユニãƒãƒ¼ã‚µãƒ«ï¼š
+ </string>
<string name="physics_desc_text">
物ç†ä½œç”¨ï¼š
</string>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
index 3df1ae8048..9b1cf1c8a4 100644
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ b/indra/newview/skins/default/xui/ja/panel_me.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="マイ プロフィール" name="panel_me">
- <panel label="マイ-ピック" name="panel_picks"/>
+<?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_outbox_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
deleted file mode 100644
index 1a14283113..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="アイテムをã“ã“ã«ãƒ‰ãƒ©ãƒƒã‚°ã‚¢ãƒ³ãƒ‰ãƒ‰ãƒ­ãƒƒãƒ—ã™ã‚‹ã¨ã€ã‚ãªãŸã®åº—é ­ã«ä¸¦ã³ã¾ã™"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 5fc4b57a08..0a295855d0 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -18,7 +18,7 @@
<string name="no_groups_msg" value="ã‚°ãƒ«ãƒ¼ãƒ—ã‚’ãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ [secondlife:///app/search/groups 検索] ã‚’ãŠè©¦ã—ãã ã•ã„。"/>
<string name="MiniMapToolTipMsg" value="[地域](ダブルクリックã§åœ°å›³ã‚’é–‹ã。Shiftâ€ãƒ‰ãƒ©ãƒƒã‚°ã§æ°´å¹³ãƒ»åž‚直移動)"/>
<string name="AltMiniMapToolTipMsg" value="[地域](ダブルクリックã§ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã€‚Shiftâ€ãƒ‰ãƒ©ãƒƒã‚°ã§æ°´å¹³ãƒ»åž‚直移動)"/>
- <string name="GroupCountWithInfo" value="ã‚ãªãŸã¯ [COUNT] グループã«å±žã—ã¦ã„ã‚‹ã®ã§ã€ã¾ã  [REMAINING] å‚加ã§ãã¾ã™ã€‚[secondlife:/// 詳細]"/>
+ <string name="GroupCountWithInfo" value="ã‚ãªãŸã¯ç¾åœ¨ã€[COUNT] グループã«å±žã—ã¦ã„ã¾ã™ã€‚ã‚㨠[REMAINING] グループã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚[secondlife:/// 上é™ã‚’増やã™]"/>
<tab_container name="tabs">
<panel label="è¿‘ã" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@
<dnd_button name="minus_btn" tool_tip="é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è„±é€€"/>
</panel>
<text name="groupcount">
- ã‚ãªãŸã¯[COUNT]グループã«å±žã—ã¦ã„ã‚‹ã®ã§ã€ã¾ã [REMAINING]å‚加ã§ãã¾ã™ã€‚
+ ã‚ãªãŸã¯ç¾åœ¨ã€[COUNT] グループã«å±žã—ã¦ã„ã¾ã™ã€‚ã‚㨠[REMAINING] グループã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
</text>
</panel>
<panel label="最新" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/ja/panel_region_environment.xml b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
index a2981012dc..444f8bae91 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="環境" name="panel_env_info">
- <text name="water_settings_title">
- ã‚ãªãŸã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã‚’訪れるユーザーã«è¦‹ã›ãŸã„ã€æ°´ã¨ç©º/デイサイクルã®è¨­å®šã‚’é¸æŠžã—ã¾ã™ã€‚詳細
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Second Life ã®ãƒ‡ãƒ•ォルト設定を使用" name="use_sl_default_settings"/>
- <radio_item label="次ã®è¨­å®šã‚’使用" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- æ°´ã®è¨­å®š
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="- 事å‰è¨­å®šã‚’é¸æŠž -" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- 空 / デイサイクル
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="空ã®å›ºå®š" name="my_sky_settings"/>
- <radio_item label="デイサイクル" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="- 事å‰è¨­å®šã‚’é¸æŠž -" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="- 事å‰è¨­å®šã‚’é¸æŠž -" name="item0"/>
- </combo_box>
- </panel>
- <button label="é©ç”¨" name="apply_btn"/>
- <button label="キャンセル" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ 既定ã®è¨­å®šã‚’使用
+ </string>
+ <string name="str_label_use_region">
+ リージョンã®è¨­å®šã‚’使用
+ </string>
+ <string name="str_altitude_desription">
+ 空 [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ 区画ãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“。環境設定ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™ã€‚
+ </string>
+ <string name="str_cross_region">
+ リージョンã®å¢ƒç•Œã§ã¯ç’°å¢ƒè¨­å®šãŒã§ãã¾ã›ã‚“。
+ </string>
+ <string name="str_legacy">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ç’°å¢ƒè¨­å®šã¯ã§ãã¾ã›ã‚“。
+ </string>
+ <string name="str_disallowed">
+ ä¸å‹•産マãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§åŒºç”»ã®ç’°å¢ƒã‚’変更ã™ã‚‹ã“ã¨ã‚’許å¯ã—ã¦ã„ã¾ã›ã‚“。
+ </string>
+ <string name="str_too_small">
+ 環境をサãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã€æœ€ä½Žã§ã‚‚ 128 平方メートルã®åŒºç”»ãŒå¿…è¦ã§ã™ã€‚
+ </string>
+ <string name="str_empty">
+ (空)
+ </string>
+ <string name="str_region_env">
+ (リージョンã®ç’°å¢ƒï¼‰
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="æŒã¡ç‰©ã‚’使ã†" name="btn_select_inventory"/>
+ <button label="カスタマイズ" name="btn_edit"/>
+ <check_box label="区画所有者ãŒç’°å¢ƒã‚’上書ãã™ã‚‹ã“ã¨ãŒã‚りã¾ã™" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ 空 [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ 䏿˜Ž
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ã“ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€ç¾åœ¨ã®ç©ºã¨ã—ã¦é¸æŠžã™ã‚‹"/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ 空 [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ 䏿˜Ž
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ã“ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€ç¾åœ¨ã®ç©ºã¨ã—ã¦é¸æŠžã™ã‚‹"/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ 空 [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ 䏿˜Ž
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ã“ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€ç¾åœ¨ã®ç©ºã¨ã—ã¦é¸æŠžã™ã‚‹"/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ 地é¢
+ </text>
+ <line_editor name="edt_invname_ground">
+ 䏿˜Ž
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ã“ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€åœ°è¡¨ãƒ¬ãƒ™ãƒ«ã®ç©ºã¨ã—ã¦é¸æŠžã—ã¾ã™ã€‚"/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ æ°´
+ </text>
+ <line_editor name="edt_invname_water">
+ 䏿˜Ž
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="æŒã¡ç‰©ã‹ã‚‰è¨­å®šã‚’ã“ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒœãƒƒã‚¯ã‚¹ã«ãƒ‰ãƒ©ãƒƒã‚°ã—ã€ç¾åœ¨ã®æ°´ã¨ã—ã¦é¸æŠžã™ã‚‹"/>
+ </panel>
+ <button label="リセット" name="btn_rst_altitudes" tool_tip="デフォルトã®é«˜åº¦ã«ãƒªã‚»ãƒƒãƒˆ"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/ja/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..56fab14f7c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="大気&光" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/ja/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..232530c5f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="雲" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/ja/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..cb746d8792
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="密度" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="レイリー指数項:" name="rayleigh_exponential"/>
+ <slider label="レイリー指数スケール:" name="rayleigh_exponential_scale"/>
+ <slider label="レイリー線形項:" name="rayleigh_linear"/>
+ <slider label="レイリー定数項:" name="rayleigh_constant"/>
+ <slider label="レイリー最大高度:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="レイリー指数項:" name="mie_exponential"/>
+ <slider label="Mie 指数スケール:" name="mie_exponential_scale"/>
+ <slider label="Mie 線形項:" name="mie_linear"/>
+ <slider label="Mie 定数項:" name="mie_constant"/>
+ <slider label="Mie ä¸ç­‰è¦ç´ ï¼š" name="mie_aniso_factor"/>
+ <slider label="Mie 最大高度:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="å¸åŽæŒ‡æ•°é …:" name="absorption_exponential"/>
+ <slider label="å¸åŽæŒ‡æ•°ã‚¹ã‚±ãƒ¼ãƒ«ï¼š" name="absorption_exponential_scale"/>
+ <slider label="å¸åŽç·šå½¢é …:" name="absorption_linear"/>
+ <slider label="å¸åŽå®šæ•°é …:" name="absorption_constant"/>
+ <slider label="å¸åŽæœ€å¤§é«˜åº¦ï¼š" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..e5026dc9fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="太陽&月" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="ビーコンを表示" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="ビーコンを表示" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_settings_water.xml b/indra/newview/skins/default/xui/ja/panel_settings_water.xml
new file mode 100644
index 0000000000..20341fcb8d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="æ°´" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ フレãƒãƒ«ãƒ»ã‚ªãƒ•セット:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_tools_texture.xml b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
index 1821a6fad6..75bc8eb86f 100644
--- a/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="テクスãƒãƒ£" name="Texture">
- <panel.string name="string repeats per meter">
- メーターã”ã¨ã«ç¹°ã‚Šè¿”ã™
- </panel.string>
- <panel.string name="string repeats per face">
- é¢ã”ã¨ã«ç¹°ã‚Šè¿”ã™
- </panel.string>
<text name="color label">
色
</text>
@@ -114,4 +108,5 @@
<spinner label="水平オフセット" name="shinyOffsetU"/>
<spinner label="垂直オフセット" name="shinyOffsetV"/>
<check_box initial_value="false" label="å¹³é¢ã‚’æƒãˆã‚‹" name="checkbox planar align" tool_tip="é¸æŠžé¢å…¨ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ã€æœ€å¾Œã«é¸æŠžã•れãŸé¢ã«æƒãˆã¾ã™ã€‚å¹³é¢ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ãƒžãƒƒãƒ”ングãŒå¿…è¦ã§ã™ã€‚"/>
+ <button label="æƒãˆã‚‹" label_selected="ç¾åœ¨ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚’æƒãˆã‚‹" name="button align textures" tool_tip="ç¾åœ¨ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚’æƒãˆã‚‹"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/role_actions.xml b/indra/newview/skins/default/xui/ja/role_actions.xml
index fe90da89c7..05eca2cca3 100644
--- a/indra/newview/skins/default/xui/ja/role_actions.xml
+++ b/indra/newview/skins/default/xui/ja/role_actions.xml
@@ -33,6 +33,7 @@
<action description="音楽ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šã‚’変更" longdescription="ストリーミングミュージックã¨å‹•ç”»ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã€ã€ŒåœŸåœ°æƒ…報〠> 「メディアã€ã‚¿ãƒ–を使ã„ã¾ã™ã€‚" name="land change media" value="20"/>
<action description="「地形を編集ã€ã«åˆ‡ã‚Šæ›¿ãˆ" longdescription="「地形を編集ã€ã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚ *警告* 「土地情報ã€ï¼žã€Œã‚ªãƒ—ションã€ï¼žã€Œåœ°å½¢ã‚’編集ã€ã®é †ã§é€²ã‚€ã¨ã€èª°ã§ã‚‚ã‚ãªãŸã®åœŸåœ°ã®å½¢ã®æ•´å‚™ã‚„ã€ãƒªãƒ³ãƒ‡ãƒ³è£½ã®æ¨¹æœ¨ã®è¨­ç½®ã€ç§»å‹•ãŒã§ãã¾ã™ã€‚ ã“ã®èƒ½åŠ›ã‚’å‰²ã‚ŠæŒ¯ã‚‹å‰ã«ã€ã“ã®ã“ã¨ã‚’よãç†è§£ã—ã¦ãŠã„ã¦ãã ã•ã„。 「土地情報ã€ï¼žã€Œã‚ªãƒ—ションã€ã‚¿ãƒ–ã‹ã‚‰ã€Œåœ°å½¢ã‚’編集ã€ã«åˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚" name="land edit" value="21"/>
<action description="「土地情報ã€ï¼žã€Œã‚ªãƒ—ションã€ã‚¿ãƒ–内ã®ã•ã¾ã–ã¾ãªè¨­å®šã‚’切り替ãˆ" longdescription="「安全(ダメージãªã—)ã€ã€ã€Œé£›è¡Œã€ã‚’切り替ãˆã€ä½äººã«ä»¥ä¸‹ã‚’許å¯ã—ã¾ã™ï¼š グループ所有地ã®ã€ŒåœŸåœ°æƒ…報〠&gt; 「オプションã€ã‚¿ãƒ–内ã®ã€ã€Œåœ°å½¢ã‚’編集ã€ã€ã€Œåˆ¶ä½œã€ã€ã€Œãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã®ä½œæˆã€ã€ã€Œã‚¹ã‚¯ãƒªãƒ—トã®å®Ÿè¡Œã€ã€‚" name="land options" value="22"/>
+ <action description="自然環境ã®è¨­å®šã¨ãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã‚’修正ã™ã‚‹ã€‚" longdescription="「土地ã«ã¤ã„ã¦ã€ &gt; 「環境ã€ã‚¿ãƒ–ã‹ã‚‰è‡ªç„¶ç’°å¢ƒã®è¨­å®šã¨ãƒ‡ã‚¤ã‚µã‚¤ã‚¯ãƒ«ã‚’変更ã™ã‚‹ã€‚" name="land change environment" value="46"/>
</action_set>
<action_set description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ã«é–¢ã™ã‚‹è¦åˆ¶ã‚’迂回ã™ã‚‹ã“ã¨ã‚’ã€ãƒ¡ãƒ³ãƒãƒ¼ã«è¨±å¯ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" name="Parcel Powers">
<action description="常ã«ã€Œåœ°å½¢ã‚’編集ã€ã‚’許å¯" longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§åœ°å½¢ã‚’編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãã®åŒºç”»ãŒã€ŒåœŸåœ°æƒ…å ±ã€ï¼žã€Œã‚ªãƒ—ションã€ã‚¿ãƒ–ã§ã‚ªãƒ•ã«ãªã£ã¦ã„ã¦ã‚‚ã€åœ°å½¢ã®ç·¨é›†ãŒå¯èƒ½ã§ã™ã€‚" name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 1e123eb619..52d6fb0c2b 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -638,6 +638,15 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="BUTTON_HELP">
ヘルプを表示
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ ã“ã®ã‚¿ã‚¤ãƒ—ã®ã‚¢ã‚¤ãƒ†ãƒ ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒŽãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰
+ã«æ·»ä»˜ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ 制é™ã®ãªã„ã€Œæ¬¡ã®æ‰€æœ‰è€…ã€ã®
+許å¯ã®ã¿ãƒŽãƒ¼ãƒˆã‚«ãƒ¼ãƒ‰ã«
+添付ã§ãã¾ã™ã€‚
+ </string>
<string name="Searching">
検索中...
</string>
@@ -717,6 +726,18 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
アップロードリクエスト中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚å•題を解決ã™ã‚‹ã«ã¯ã€ã‚µãƒãƒ¼ãƒˆ
(http://secondlife.com/support)ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
</string>
+ <string name="SettingValidationError">
+ インãƒãƒ¼ãƒˆã™ã‚‹è¨­å®š [NAME] ã®æ¤œè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </string>
+ <string name="SettingImportFileError">
+ ファイル [FILE] ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“
+ </string>
+ <string name="SettingParseFileError">
+ ファイル [FILE] ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“
+ </string>
+ <string name="SettingTranslateError">
+ éŽåŽ»ã®ã‚¦ã‚¤ãƒ³ãƒ‰ãƒ©ã‚¤ãƒˆ [NAME] を変æ›ã§ãã¾ã›ã‚“
+ </string>
<string name="texture">
テクスãƒãƒ£
</string>
@@ -792,6 +813,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="symbolic folder link">
フォルダã®ãƒªãƒ³ã‚¯
</string>
+ <string name="settings blob">
+ 設定
+ </string>
<string name="mesh">
メッシュ
</string>
@@ -1122,6 +1146,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ForceSitAvatar">
ã‚¢ãƒã‚¿ãƒ¼ã‚’強制的ã«åº§ã‚‰ã›ã‚‹
</string>
+ <string name="ChangeEnvSettings">
+ 自然環境ã®è¨­å®šã‚’変更ã™ã‚‹
+ </string>
<string name="NotConnected">
接続ã•れã¦ã„ã¾ã›ã‚“
</string>
@@ -1273,6 +1300,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="tattoo">
タトゥ
</string>
+ <string name="universal">
+ ユニãƒãƒ¼ã‚µãƒ«
+ </string>
<string name="physics">
物ç†ä½œç”¨
</string>
@@ -1315,6 +1345,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="tattoo_not_worn">
タトゥー未ç€ç”¨
</string>
+ <string name="universal_not_worn">
+ ユニãƒãƒ¼ã‚µãƒ«ãªã—
+ </string>
<string name="physics_not_worn">
物ç†ä½œç”¨ãªã—
</string>
@@ -1366,6 +1399,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="create_new_tattoo">
æ–°ã—ã„タトゥを作æˆ
</string>
+ <string name="create_new_universal">
+ æ–°ã—ã„ユニãƒãƒ¼ã‚µãƒ«ã‚’作æˆ
+ </string>
<string name="create_new_physics">
æ–°ã—ã„物ç†ä½œç”¨ã‚’作æˆ
</string>
@@ -1608,11 +1644,14 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="MarketplaceUpdating">
アップデート中...
</string>
+ <string name="UploadFeeInfo">
+ 料金ã¯ã‚µãƒ–スクリプションã®ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚Šç•°ãªã‚Šã¾ã™ã€‚レベルãŒé«˜ã„ã»ã©ã€æ–™é‡‘ãŒä¸‹ãŒã‚Šã¾ã™ã€‚[https://secondlife.com/my/account/membership.php? 詳細]
+ </string>
<string name="Open landmarks">
- ランドマークを開ã
+ オープン ランドマーク
</string>
<string name="Unconstrained">
- éžæ‹˜æŸ
+ アンコンストレインド(制約ãªã—)
</string>
<string name="no_transfer" value=" (å†è²©ãƒ»ãƒ—レゼントä¸å¯ï¼‰"/>
<string name="no_modify" value=" (編集ä¸å¯ï¼‰"/>
@@ -2512,6 +2551,27 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="RegionSettings">
リージョン(地域)ã®è¨­å®š
</string>
+ <string name="NoEnvironmentSettings">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¯ç’°å¢ƒè¨­å®šã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。
+ </string>
+ <string name="EnvironmentSun">
+ 太陽
+ </string>
+ <string name="EnvironmentMoon">
+ 月
+ </string>
+ <string name="EnvironmentBloom">
+ 花
+ </string>
+ <string name="EnvironmentCloudNoise">
+ 雲ã®éŸ³
+ </string>
+ <string name="EnvironmentNormalMap">
+ ノーマル・マップ
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparent
+ </string>
<string name="ClassifiedClicksTxt">
クリック数: [TELEPORT] テレãƒãƒ¼ãƒˆã€ [MAP] 地図〠[PROFILE] プロフィール
</string>
@@ -4728,6 +4788,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="New Tattoo">
æ–°ã—ã„タトゥ
</string>
+ <string name="New Universal">
+ æ–°ã—ã„ユニãƒãƒ¼ã‚µãƒ«
+ </string>
<string name="New Physics">
æ–°è¦ã®ç‰©ç†ä½œç”¨
</string>
@@ -4854,6 +4917,15 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Female - Wow">
女性 - Wow
</string>
+ <string name="New Daycycle">
+ æ–°ã—ã„デイサイクル
+ </string>
+ <string name="New Water">
+ æ–°ã—ã„æ°´
+ </string>
+ <string name="New Sky">
+ æ–°ã—ã„空
+ </string>
<string name="/bow">
/ãŠã˜ãŽã™ã‚‹
</string>
@@ -5026,6 +5098,15 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Chat" value=" ãƒãƒ£ãƒƒãƒˆï¼š">
ãƒãƒ£ãƒƒãƒˆ
</string>
+ <string name="BaseMembership">
+ ベース
+ </string>
+ <string name="PremiumMembership">
+ プレミアム
+ </string>
+ <string name="Premium PlusMembership">
+ プレミアムプラス
+ </string>
<string name="DeleteItems">
é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹
</string>
@@ -5382,6 +5463,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="BeaconMedia">
メディアビーコン(白)を表示中
</string>
+ <string name="BeaconSun">
+ å¤ªé™½ã®æ–¹è§’ビーコン(オレンジ)を表示中
+ </string>
+ <string name="BeaconMoon">
+ æœˆã®æ–¹è§’ビーコン(紫)を表示中
+ </string>
<string name="ParticleHiding">
パーティクルをéžè¡¨ç¤º
</string>
@@ -5409,6 +5496,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Command_Destinations_Label">
行ãå…ˆ
</string>
+ <string name="Command_Environments_Label">
+ ç§ã®ç’°å¢ƒ
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5502,6 +5595,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Command_Destinations_Tooltip">
行ã£ã¦ã¿ãŸã„場所
</string>
+ <string name="Command_Environments_Tooltip">
+ ç§ã®ç’°å¢ƒ
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Facebook ã¸æŠ•ç¨¿
+ </string>
<string name="Command_Flickr_Tooltip">
Flickr ã«ã‚¢ãƒƒãƒ—ロード
</string>
@@ -5697,6 +5796,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="ExperiencePermission12">
ä½“é¨“ã®æ¨©é™ã‚’è‡ªå‹•çš„ã«æ‰¿è«¾
</string>
+ <string name="ExperiencePermission16">
+ ã‚ãªãŸã®ã‚¢ãƒã‚¿ãƒ¼ã‚’強制的ã«åº§ã‚‰ã›ã‚‹
+ </string>
+ <string name="ExperiencePermission17">
+ 自然環境ã®è¨­å®šã‚’変更ã™ã‚‹
+ </string>
<string name="ExperiencePermissionShortUnknown">
ãŒä¸æ˜Žãªæ“作を実行ã—ã¾ã—ãŸï¼š [Permission]
</string>
@@ -5721,6 +5826,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="ExperiencePermissionShort12">
権é™
</string>
+ <string name="ExperiencePermissionShort16">
+ Sit
+ </string>
+ <string name="ExperiencePermissionShort17">
+ 環境
+ </string>
<string name="logging_calls_disabled_log_empty">
会話ã¯ãƒ­ã‚°ã«è¨˜éŒ²ã•れã¦ã„ã¾ã›ã‚“。ログã®è¨˜éŒ²ã‚’é–‹å§‹ã™ã‚‹ã«ã¯ã€ã€Œç’°å¢ƒè¨­å®šã€&gt;「ãƒãƒ£ãƒƒãƒˆã€ã§ã€Œä¿å­˜: ログã®ã¿ã€ã¾ãŸã¯ã€Œä¿å­˜: ログã¨ä¼šè©±ã®ãƒ†ã‚­ã‚¹ãƒˆã€ã‚’é¸æŠžã—ã¾ã™ã€‚
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
index 72167e0d3c..a1d703a15a 100644
--- a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
@@ -50,8 +50,7 @@
</text>
<button label="Kup teraz" name="buy_btn" />
<button label="Anuluj" name="cancel_btn" />
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
Nie można kupić
- </text>
- <button label="Odwiedź stronę WWW" name="error_web" />
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml
deleted file mode 100644
index fc750715c6..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<floater name="Delete Env Preset" title="USUŃ UST. OTOCZENIA">
- <string name="title_water">
- Usuń Ustawienie wody
- </string>
- <string name="title_sky">
- Usuń Ustawienie nieba
- </string>
- <string name="title_day_cycle">
- Usuń cykl dnia
- </string>
- <string name="label_water">
- Wybierz:
- </string>
- <string name="label_sky">
- Wybierz:
- </string>
- <string name="label_day_cycle">
- Cykl dnia:
- </string>
- <string name="msg_confirm_deletion">
- Masz absolutną pewność, że chcesz usunąć wybrane Ustawienie?
- </string>
- <string name="msg_sky_is_referenced">
- Nie można usunąć Ustawienia odwołującego się do jakiegoś cyklu dnia.
- </string>
- <string name="combo_label">
- -Wybierz Ustawienie-
- </string>
- <text name="label">
- Wybierz:
- </text>
- <button label="Usuń" name="delete" />
- <button label="Anuluj" name="cancel" />
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml
deleted file mode 100644
index 9cc88ba288..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="SKRZYNKA NADAWCZA KUPCA">
- <string name="OutboxFolderCountN">
- Folderów: [NUM]
- </string>
- <string name="OutboxImporting">
- Wysyłanie folderów...
- </string>
- <string name="OutboxInitializing">
- Inicjalizacja...
- </string>
- <panel name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Åadowanie...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Przeciągaj tu przedmioty by tworzyć foldery
- </text>
- </panel>
- <button label="Wyślij na Marketplace" tool_tip="Wyślij na witrynę Marketplace" name="outbox_import_btn" />
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
index 8ac158b462..2425213160 100644
--- a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
@@ -9,13 +9,10 @@
<text name="Multiple">
Wiele tekstur
</text>
- <radio_group name="mode_selection">
- <radio_item label="Szafa" name="inventory" />
- <radio_item label="Lokalna" name="local" />
- </radio_group>
- <text name="unknown">
- Rozm.: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Szafa" name="inventory" />
+ <combo_box.item label="Lokalna" name="local" />
+ </combo_box>
<button label="Domyślna" label_selected="Domyślna" name="Default" />
<button label="Pusta" label_selected="Pusta" name="Blank" />
<button label="Przezrocz." label_selected="Przezrocz." name="None" />
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
index add2d59998..f5fbf5c0c1 100644
--- a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Dotknij" name="touch_attach" />
+ <menu_item_call label="Edytuj" name="edit_item" />
<menu_item_call label="Odłącz" name="detach" />
</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_inventory.xml b/indra/newview/skins/default/xui/pl/menu_inventory.xml
index 0edb680b16..1aeffc58b7 100644
--- a/indra/newview/skins/default/xui/pl/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inventory.xml
@@ -85,6 +85,7 @@
<menu_item_call label="Załóż" name="Wearable And Object Wear" />
<menu label="Dołącz do" name="Attach To" />
<menu label="Dołącz do HUD-a" name="Attach To HUD" />
+ <menu_item_call label="Dotknij" name="Attachment Touch" />
<menu_item_call label="Edytuj" name="Wearable Edit" />
<menu_item_call label="Dodaj/dołącz" name="Wearable Add" />
<menu_item_call label="Zdejmij" name="Take Off" />
diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index e6ad1faee6..4d03e7c780 100644
--- a/indra/newview/skins/default/xui/pl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml
@@ -84,17 +84,14 @@
<menu name="Water Presets" label="Ustawienia wody">
<menu_item_call label="Nowe Ustawienie..." name="new_water_preset" />
<menu_item_call label="Edytuj Ustawienie..." name="edit_water_preset" />
- <menu_item_call label="Usuń Ustawienie..." name="delete_water_preset" />
</menu>
<menu name="Sky Presets" label="Ustawienia nieba">
<menu_item_call label="Nowe Ustawienie..." name="new_sky_preset" />
<menu_item_call label="Edytuj Ustawienie..." name="edit_sky_preset" />
- <menu_item_call label="Usuń Ustawienie..." name="delete_sky_preset" />
</menu>
<menu name="Day Presets" label="Ustawienia pory dnia">
<menu_item_call label="Nowe Ustawienie..." name="new_day_preset" />
<menu_item_call label="Edytuj Ustawienie..." name="edit_day_preset" />
- <menu_item_call label="Usuń Ustawienie..." name="delete_day_preset" />
</menu>
</menu>
</menu>
@@ -159,7 +156,7 @@
<menu_item_call label="Dźwięk ([COST]L$)..." name="Upload Sound" />
<menu_item_call label="AnimacjÄ™ ([COST]L$)..." name="Upload Animation" />
<menu_item_call label="Model meszowy..." name="Upload Model" />
- <menu_item_call label="Zbiór wielu plików ([COST]L$ per file)..." name="Bulk Upload" />
+ <menu_item_call label="Zbiór wielu plików..." name="Bulk Upload" />
</menu>
<menu_item_call label="Cofnij" name="Undo" />
<menu_item_call label="Ponów" name="Redo" />
diff --git a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
index 260b86cb07..b0ef8e4393 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="ZastÄ…p" name="wear_replace" />
<menu_item_call label="Załóż" name="wear_wear" />
<menu_item_call label="Dodaj" name="wear_add" />
+ <menu_item_call label="Dotknij" name="touch" />
<menu_item_call label="Zdejmij/Odłącz" name="take_off_or_detach" />
<menu_item_call label="Odłącz" name="detach" />
<context_menu label="Dołącz do" name="wearable_attach_to" />
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
index 73138b2cf7..c129448adc 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Edytuj strój" name="edit" />
+ <menu_item_call label="Dotknij" name="touch"/>
+ <menu_item_call label="Edytuj" name="edit_item"/>
+ <menu_item_call label="Edytuj strój" name="edit_outfit" />
<menu_item_call label="Zdejmij" name="takeoff" />
<menu_item_call label="Kopiuj listę przedmiotów stroju do schowka" name="copy" />
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
index 09c82da427..188f77a3bb 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu name="Wearing">
+ <menu_item_call label="Dotknij" name="touch_attach"/>
+ <menu_item_call label="Edytuj" name="edit_item"/>
<menu_item_call label="Zdejmij" name="take_off" />
<menu_item_call label="Odłącz" name="detach" />
- <menu_item_call label="Edytuj strój" name="edit" />
+ <menu_item_call label="Edytuj strój" name="edit_outfit" />
</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml
deleted file mode 100644
index 01d0455215..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel name="inventory_outbox" tool_tip="Przeciągnij i upuść tutaj przedmioty, aby przygotować je do sprzedaży na Twojej witrynie Marketplace" />
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
index 738805d800..e8c400dbd1 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
@@ -28,7 +28,6 @@
<check_box label="Przezroczysta woda" name="TransparentWater" />
<check_box label="Mapping wypukłości i połysk" name="BumpShiny" />
<check_box label="Lokalne światła" name="LocalLights" />
- <check_box label="Podstawowe shadery" name="BasicShaders" tool_tip="Wyłączenie tej opcji może naprawić błędy niektórych sterowników graficznych" />
<check_box label="Shadery atmosfery" name="WindLightUseAtmosShaders" />
<check_box label="Zaawansowane oświetlenie" name="UseLightShaders" />
<check_box label="Okluzja otoczenia" name="UseSSAO" />
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index 9aece1221d..91fea234d2 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -710,6 +710,9 @@ Spróbuj zalogować się ponownie za minutę.
<string name="mesh">
mesz
</string>
+ <string name="settings">
+ ustawień
+ </string>
<string name="AvatarEditingAppearance">
(Edycja wyglÄ…du)
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml
index ef71baa0b6..d7741fa902 100644
--- a/indra/newview/skins/default/xui/pt/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml
@@ -362,11 +362,11 @@ Apenas lotes maiores podem ser listados na busca.
Foto:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clique para escolher uma imagem"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Avatares em outros lotes podem ver e conversar com avatares neste lote
</text>
- <check_box label="Ver avatares" name="SeeAvatarsCheck" tool_tip="Permite que os avatares em outros lotes vejam e batam papo com avatares neste lote. Você poderá vê-los e conversar com eles."/>
- <text name="landing_point">
+ <check_box label="Ver avatares" name="SeeAvatarsCheck" top="170" tool_tip="Permite que os avatares em outros lotes vejam e batam papo com avatares neste lote. Você poderá vê-los e conversar com eles."/>
+ <text name="landing_point" width="225">
Ponto de Aterrissagem: [LANDING]
</text>
<button label="Definir" label_selected="Definir" name="Set" tool_tip="Define o ponto de aterrissagem de visitantes. Define para o ponto em que seu avatar se encontra neste lote."/>
@@ -479,5 +479,6 @@ Mídia:
</panel>
</panel>
<panel label="EXPERIÊNCIAS" name="land_experiences_panel"/>
+ <panel label="AMBIENTE" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_adjust_environment.xml b/indra/newview/skins/default/xui/pt/floater_adjust_environment.xml
new file mode 100644
index 0000000000..4e2e96c54b
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Iluminação pessoal">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Redefinir" name="btn_reset" tool_tip="Feche e redefina e Compartilhe o Ambiente"/>
+ <text name="cloud_map_label">
+ Imagem de nuvem:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Dom:
+ </text>
+ <check_box label="Exibir baliza" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Exibir baliza" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_beacons.xml b/indra/newview/skins/default/xui/pt/floater_beacons.xml
index f8ae3cd2d8..bcd6ae0400 100644
--- a/indra/newview/skins/default/xui/pt/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/pt/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Fontes de som" name="sounds"/>
<check_box label="Fontes de partículas" name="particles"/>
<check_box label="Fontes de mídia" name="moapbeacon"/>
+ <check_box label="Dom" name="sun"/>
+ <check_box label="Lua" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml b/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
index a31b049345..554865b3a6 100644
--- a/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
@@ -30,6 +30,7 @@
<icon name="icon_sound" tool_tip="Sons"/>
<check_box label="Texturas" name="check_texture"/>
<icon name="icon_texture" tool_tip="Texturas"/>
+ <icon name="icon_setting" tool_tip="Configurações de ambiente"/>
<button label="Tudo" label_selected="Todas" name="check_all"/>
<button label="Limpar" label_selected="Nenhuma" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
index 513400954b..c740b90472 100644
--- a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="Comprar já!" name="buy_btn"/>
<button label="Fechar" name="cancel_btn"/>
- <text name="info_cannot_buy" font="SansSerifBig">
+ <floater.string name="info_cannot_buy">
Transação incompleta
- </text>
- <button label="Prosseguir para a web" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
deleted file mode 100644
index 2434f67d6c..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="EXCLUIR PREDEFINIÇÃO ENV">
- <string name="title_water">
- Excluir predefinição da água
- </string>
- <string name="title_sky">
- Excluir predefinição de céu
- </string>
- <string name="title_day_cycle">
- Excluir ciclo de dias
- </string>
- <string name="label_water">
- Predefinição:
- </string>
- <string name="label_sky">
- Predefinição:
- </string>
- <string name="label_day_cycle">
- Ciclos de dias:
- </string>
- <string name="msg_confirm_deletion">
- Tem certeza de que quer excluir a predefinição selecionada?
- </string>
- <string name="msg_sky_is_referenced">
- Não é possível remover uma predefinição que está referenciada por algum(ns) ciclo(s) de dias.
- </string>
- <string name="combo_label">
- -Selecionar uma prefefinição-
- </string>
- <text name="label">
- Predefinição:
- </text>
- <button label="Excluir" name="delete"/>
- <button label="Cancelar" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/pt/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..f58af73e55
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Editar ciclo de dias">
+ <string name="title_new">
+ Criar um ciclo de dias
+ </string>
+ <string name="title_edit">
+ Editar ciclo de dia
+ </string>
+ <string name="hint_new">
+ Nomeie o seu ciclo de dias, ajustar os controles para criá-lo e clique em “Salvarâ€.
+ </string>
+ <string name="hint_edit">
+ Editar o seu ciclo de dias, ajustar os controles para criá-lo e clique em “Salvarâ€.
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Céu [ALT]
+ </string>
+ <string name="sky_label">
+ Céu
+ </string>
+ <string name="water_label">
+ Ãgua
+ </string>
+ <string name="commit_parcel">
+ Aplicar ao lote
+ </string>
+ <string name="commit_region">
+ Aplicar para a região
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Nome do ciclo de dias:
+ </text>
+ <button label="Importar" name="btn_import" tool_tip="Importar configurações do legado do disco."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Céu 4" name="sky4_track"/>
+ <button label="Céu 3" name="sky3_track"/>
+ <button label="Céu 2" name="sky2_track"/>
+ <button label="A nível do chão" name="sky1_track"/>
+ <button label="Ãgua" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Clonar Rastreio de" name="copy_track"/>
+ <button label="Carregar rastreio de" name="load_track"/>
+ <button label="Limpar rastreio" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Passo para trás"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Passo para frente"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="Adicionar [FRAME]" name="add_frame"/>
+ <button label="Carregar [FRAME]" name="btn_load_frame"/>
+ <button label="Excluir [FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Selecionar uma estrutura chave da linha do tempo acima para editar as configurações.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Ãgua" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmosfera e Claridade" name="atmosphere_panel"/>
+ <panel label="Nuvens" name="clouds_panel"/>
+ <panel label="Sol e Lua" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Salvar" name="save_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/pt/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..c969aac74e
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Ambiente consertado">
+ <string name="edit_sky">
+ Editar céu:
+ </string>
+ <string name="edit_water">
+ Editar água:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Carregar" name="btn_load" tool_tip="Carregar as configurações de inventário"/>
+ <button label="Importar" name="btn_import" tool_tip="Importar configurações do legado do disco."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Salvar" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Cancelar" name="btn_cancel" tool_tip="Voltar à última versão salva"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
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 3f66fd07b9..c50d7dcda0 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
@@ -12,6 +12,7 @@
<check_box label="Sons" name="check_sound"/>
<check_box label="Texturas" name="check_texture"/>
<check_box label="Fotos" name="check_snapshot"/>
+ <check_box label="Configurações" name="check_settings"/>
<button label="Tudo" label_selected="Tudo" name="All"/>
<button label="Nenhum" label_selected="Nenhum" name="None"/>
<check_box label="Sempre mostrar as pastas" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
deleted file mode 100644
index 3beada1fc0..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="CAIXA DE SAÃDA DO LOJISTA">
- <string name="OutboxFolderCount1">
- 1 pasta
- </string>
- <string name="OutboxFolderCountN">
- [NUM] pasta(s)
- </string>
- <string name="OutboxImporting">
- Enviando pastas...
- </string>
- <string name="OutboxInitializing">
- Iniciando...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Carregando...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Arraste itens para cá para criar pastas
- </text>
- </panel>
- <button label="Enviar para Mercado" name="outbox_import_btn" tool_tip="Enviar para a frente da minha loja do mercado"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_my_environments.xml b/indra/newview/skins/default/xui/pt/floater_my_environments.xml
new file mode 100644
index 0000000000..71c1a33f58
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Lugares" name="my_environments" title="MEUS AMBIENTES">
+ <layout_stack>
+ <layout_panel label="Filtros" name="filter_panel">
+ <check_box label="Dias" name="chk_days"/>
+ <check_box label="Céus" name="chk_skies"/>
+ <check_box label="Ãgua" name="chk_water"/>
+ <filter_editor label="Filtrar Ambientes" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Ambientes" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Exibir todas as pastas" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Mais opções"/>
+ <menu_button name="btn_newsettings" tool_tip="Criar nova configuração"/>
+ <button name="btn_del" tool_tip="Remover item selecionado"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_perms_default.xml b/indra/newview/skins/default/xui/pt/floater_perms_default.xml
index 40659a353a..0b8914b4dd 100644
--- a/indra/newview/skins/default/xui/pt/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/pt/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Definir permissões padrão para roupas ou partes do corpo criadas">
Itens de vestuário
</text>
+ <text name="label_13" tool_tip="Definir permissões padrão para quando as configurações do Ambiente forem criadas">
+ Configurações
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Cancelar" label_selected="Cancelar" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_pick_track.xml b/indra/newview/skins/default/xui/pt/floater_pick_track.xml
new file mode 100644
index 0000000000..dc09f262c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="ESCOLHER: RASTREAR">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Selecionar o céu de origem:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Céu4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Céu3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Céu2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Chão" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Cancelar" label_selected="Cancelar" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml
index c5039267ca..bbe36e3e03 100644
--- a/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Ãgua transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Mapeamento de relevo e brilho" name="BumpShiny"/>
<check_box initial_value="true" label="Luzes locais" name="LocalLights"/>
- <check_box initial_value="true" label="Sombreamento simples" name="BasicShaders" tool_tip="Desativar essa opção pode evitar o travamento de alguns drivers de placas gráficas"/>
<slider label="Detalhes do terreno:" name="TerrainDetail"/>
<text name="TerrainDetailText">
Baixo
diff --git a/indra/newview/skins/default/xui/pt/floater_settings_picker.xml b/indra/newview/skins/default/xui/pt/floater_settings_picker.xml
new file mode 100644
index 0000000000..0dc80989be
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="ESCOLHER: CONFIGURAÇÕES">
+ <floater.string name="pick title">
+ Escolher:
+ </floater.string>
+ <floater.string name="pick_track">
+ SELECIONE RASTREIO
+ </floater.string>
+ <floater.string name="pick_settings">
+ SELECIONAR CONFIGURAÇÕES
+ </floater.string>
+ <floater.string name="track_water">
+ Ãgua
+ </floater.string>
+ <floater.string name="track_ground">
+ Chão
+ </floater.string>
+ <floater.string name="track_sky">
+ Céu[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Filtrar texturas" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Cancelar" label_selected="Cancelar" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
index ba4ef0afde..d3eec114e2 100644
--- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
@@ -9,17 +9,13 @@
<text name="Multiple">
Multiplas texturas
</text>
- <radio_group name="mode_selection">
- <radio_item label="Inventário" name="inventory" value="0"/>
- <radio_item label="Local" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Tamanho: [DIMENSÕES]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Inventário" name="inventory" value="0"/>
+ <combo_box.item label="Local" name="local" value="1"/>
+ </combo_box>
<button label="Padrão" label_selected="Padrão" name="Default"/>
<button label="Branco" label_selected="Branco" name="Blank"/>
<button label="Nenhum" label_selected="Nenhum" name="None"/>
- <check_box initial_value="true" label="Inscrever-se agora" name="apply_immediate_check"/>
<text name="preview_disabled" value="Visualização desativada"/>
<filter_editor label="Filtrar texturas" name="inventory search editor"/>
<check_box initial_value="false" label="Exibir pastas" name="show_folders_check"/>
@@ -30,6 +26,22 @@
<column label="Nome" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Escolha a textura de assar">
+ <combo_box.item label="Nenhum" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Ocultar região da mesh de base" name="hide_base_mesh_region"/>
<button label="OK" label_selected="OK" name="Select"/>
<button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
+ <check_box initial_value="true" label="Inscrever-se agora" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
index 527e3af3c9..5072b54f06 100644
--- a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Tocar" name="touch_attach" />
+ <menu_item_call label="Editar" name="edit_item" />
<menu_item_call label="Separar" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml
index b99ddc67d2..363ed43986 100644
--- a/indra/newview/skins/default/xui/pt/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Ativar" name="Marketplace Activate"/>
<menu_item_call label="Desativar" name="Marketplace Deactivate"/>
<menu_item_call label="Compartilhar" name="Share"/>
- <menu_item_call label="Comprar" name="Task Buy"/>
<menu_item_call label="Abrir" name="Task Open"/>
<menu_item_call label="Executar" name="Task Play"/>
<menu_item_call label="Propriedades" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Nova roupa de baixo" name="New Underpants"/>
<menu_item_call label="Nova máscara alfa" name="New Alpha Mask"/>
<menu_item_call label="Nova tatuagem" name="New Tattoo"/>
+ <menu_item_call label="Novo universal" name="New Universal"/>
<menu_item_call label="Novo físico" name="New Physics"/>
</menu>
<menu label="Nova parte do corpo" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Novo cabelo" name="New Hair"/>
<menu_item_call label="Novos olhos" name="New Eyes"/>
</menu>
+ <menu label="Novas configurações" name="New Settings">
+ <menu_item_call label="Novo céu" name="New Sky"/>
+ <menu_item_call label="Nova água" name="New Water"/>
+ <menu_item_call label="Novo ciclo de dias" name="New Day Cycle"/>
+ </menu>
<menu label="Usar como padrão para" name="upload_def">
<menu_item_call label="Envios de imagem" name="Image uploads"/>
<menu_item_call label="Envios de som" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Vestir" name="Wearable And Object Wear"/>
<menu label="Anexar a" name="Attach To"/>
<menu label="Anexar ao HUD" name="Attach To HUD"/>
+ <menu_item_call label="Tocar" name="Attachment Touch" />
<menu_item_call label="Editar" name="Wearable Edit"/>
<menu_item_call label="Adicionar" name="Wearable Add"/>
<menu_item_call label="Tirar" name="Take Off"/>
+ <menu_item_call label="Aplicar somente a mim" name="Settings Apply Local"/>
+ <menu_item_call label="Aplicar ao lote" name="Settings Apply Parcel"/>
<menu_item_call label="Copiar para Listagens do Marketplace" name="Marketplace Copy"/>
<menu_item_call label="Mover para Listagens do Marketplace" name="Marketplace Move"/>
<menu_item_call label="--Sem opções--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
index 7a7ebc50af..0eaf3c7c5f 100644
--- a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Som (L$[COST])..." name="Upload Sound"/>
<menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/>
<menu_item_call label="Modelar..." name="Upload Model"/>
- <menu_item_call label="Assistente de modelagem..." name="Upload Model Wizard"/>
- <menu_item_call label="Volume (L$[COST] per file)..." name="Bulk Upload"/>
- <menu_item_call label="Autorizações de upload padrão" name="perm prefs"/>
+ <menu_item_call label="Volume..." name="Bulk Upload"/>
</menu>
<menu_item_call label="Nova pasta" name="New Folder"/>
<menu_item_call label="Novo script" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Novas roupa de baixo" name="New Underpants"/>
<menu_item_call label="Novo alpha" name="New Alpha"/>
<menu_item_call label="Nova tatuagem" name="New Tattoo"/>
+ <menu_item_call label="Novo universal" name="New Universal"/>
<menu_item_call label="Novo físico" name="New Physics"/>
</menu>
<menu label="Nova parte do corpo" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Novo cabelo" name="New Hair"/>
<menu_item_call label="Novos olhos" name="New Eyes"/>
</menu>
+ <menu label="Novas configurações" name="New Settings">
+ <menu_item_call label="Novo céu" name="New Sky"/>
+ <menu_item_call label="Nova água" name="New Water"/>
+ <menu_item_call label="Novo ciclo de dias" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
index ccf65ae566..1de8fd939b 100644
--- a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Novo alpha" name="New Alpha"/>
<menu_item_call label="Novo físico" name="New Physics"/>
<menu_item_call label="Nova tatuagem" name="New Tattoo"/>
+ <menu_item_call label="Novo universal" name="New Universal"/>
</menu>
<menu label="Nova parte do corpo" name="New Body Parts">
<menu_item_call label="Nova silhueta" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_save_settings.xml b/indra/newview/skins/default/xui/pt/menu_save_settings.xml
new file mode 100644
index 0000000000..9af5d01629
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Salvar" name="save_settings"/>
+ <menu_item_check label="Salvar como" name="save_as_new_settings"/>
+ <menu_item_check label="Enviar" name="commit_changes"/>
+ <menu_item_check label="Aplicar somente a mim" name="apply_local"/>
+ <menu_item_check label="Aplicar ao lote" name="apply_parcel"/>
+ <menu_item_check label="Aplicar para a região" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_settings_add.xml b/indra/newview/skins/default/xui/pt/menu_settings_add.xml
new file mode 100644
index 0000000000..3bd87e6c12
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Novo céu" name="New Sky"/>
+ <menu_item_call label="Nova água" name="New Water"/>
+ <menu_item_call label="Novo ciclo de dias" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_settings_gear.xml b/indra/newview/skins/default/xui/pt/menu_settings_gear.xml
new file mode 100644
index 0000000000..55817b22e0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Editar" name="edit_settings"/>
+ <menu_item_call label="Aplicar somente a mim" name="Settings Apply Local"/>
+ <menu_item_call label="Aplicar ao lote" name="Settings Apply Parcel"/>
+ <menu_item_call label="Aplicar para a região" name="Settings Apply Region"/>
+ <menu_item_call label="Copiar" name="copy_settings"/>
+ <menu_item_call label="Colar" name="paste_settings"/>
+ <menu_item_call label="Copiar UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index e82b7bc62a..8b144390fa 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -79,30 +79,15 @@
<menu_item_check label="Propriedades do lote" name="Parcel Properties"/>
<menu_item_check label="Menu avançado" name="Show Advanced Menu"/>
</menu>
- <menu label="Dom" name="Sun">
+ <menu label="Ambiente" name="Environment">
<menu_item_check label="Nascer do sol" name="Sunrise"/>
<menu_item_check label="Meio-dia" name="Noon"/>
<menu_item_check label="Pôr do sol" name="Sunset"/>
<menu_item_check label="Meia-noite" name="Midnight"/>
- <menu_item_check label="Usar as configurações da região" name="Use Region Settings"/>
- </menu>
- <menu label="Editor de ambientes" name="Environment Editor">
- <menu_item_call label="Configurações do ambiente..." name="Environment Settings"/>
- <menu label="Predefinições da água" name="Water Presets">
- <menu_item_call label="Nova predefinição..." name="new_water_preset"/>
- <menu_item_call label="Editar predefinição..." name="edit_water_preset"/>
- <menu_item_call label="Excluir predefinição..." name="delete_water_preset"/>
- </menu>
- <menu label="Predefinições de céu" name="Sky Presets">
- <menu_item_call label="Nova predefinição..." name="new_sky_preset"/>
- <menu_item_call label="Editar predefinição..." name="edit_sky_preset"/>
- <menu_item_call label="Excluir predefinição..." name="delete_sky_preset"/>
- </menu>
- <menu label="Predefinições do dia" name="Day Presets">
- <menu_item_call label="Nova predefinição..." name="new_day_preset"/>
- <menu_item_call label="Editar predefinição..." name="edit_day_preset"/>
- <menu_item_call label="Excluir predefinição..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Use o ambiente compartilhado" name="Use Shared Environment"/>
+ <menu_item_call label="Meu ambiente..." name="my_environs"/>
+ <menu_item_call label="Iluminação pessoal..." name="adjustment_tool"/>
+ <menu_item_check label="Pausar as nuvens" name="pause_clouds"/>
</menu>
</menu>
<menu label="Construir" name="BuildTools">
@@ -323,6 +308,9 @@
<menu_item_check label="Máscaras alpha automáticas (sem adiar)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texturas de animação" name="Animation Textures"/>
<menu_item_check label="Desativar texturas" name="Disable Textures"/>
+ <menu_item_check label="Desativar ambiente" name="Disable Ambient"/>
+ <menu_item_check label="Desabilitar a luz solar" name="Disable Sunlight"/>
+ <menu_item_check label="Desativar Luzes locais" name="Disable Local Lights"/>
<menu_item_check label="Render Attached Lights" name="Render Attached Lights"/>
<menu_item_check label="Render Attached Particles" name="Render Attached Particles"/>
<menu_item_check label="Objetos iridescentes" name="Hover Glow Objects"/>
@@ -413,6 +401,7 @@
</menu>
<menu label="Admin" name="Deprecated">
<menu label="Take Off Clothing" name="Take Off Clothing">
+ <menu_item_call label="Universal" name="Universal"/>
<menu_item_call label="Físico" name="Physics"/>
</menu>
<menu label="Ajuda" name="DeprecatedHelp">
diff --git a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
index 2487f6779f..2d16736277 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Trocar" name="wear_replace"/>
<menu_item_call label="Vestir" name="wear_wear"/>
<menu_item_call label="Adicionar" name="wear_add"/>
+ <menu_item_call label="Tocar" name="touch" />
<menu_item_call label="Tirar / Separar" name="take_off_or_detach"/>
<menu_item_call label="Separar" name="detach"/>
<context_menu label="Colocar em" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
index 75dca703cb..bc24ffcdd9 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Editar look" name="edit"/>
+ <menu_item_call label="Tocar" name="touch"/>
+ <menu_item_call label="Editar" name="edit_item"/>
+ <menu_item_call label="Editar look" name="edit_outfit"/>
<menu_item_call label="Tirar" name="takeoff"/>
<menu_item_call label="Copiar lista do look para a área de transferência" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
index 42aa386215..d00fd9ae28 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Tocar" name="touch_attach"/>
<menu_item_call label="Tirar" name="take_off"/>
<menu_item_call label="Tirar" name="detach"/>
- <menu_item_call label="Editar look" name="edit"/>
+ <menu_item_call label="Editar look" name="edit_outfit"/>
<menu_item_call label="Editar" name="edit_item"/>
<menu_item_call label="Mostrar original" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 530a272dbb..bd1185bdd2 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -265,6 +265,10 @@ Deseja conceder direitos de modificação para os residentes selecionados?
Você quer revogar os direitos de edição para os residentes selecionados?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ O nome do grupo deve conter entre [MIN_LEN] e [MAX_LEN] caracteres.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
Não foi possível criar um grupo.
[MESSAGE]
@@ -359,7 +363,7 @@ Deseja continuar?
Você não tem L$ suficientes para associar-se a este grupo.
</notification>
<notification name="CreateGroupCost">
- Criar este grupo custa L$100.
+ Criar este grupo custará L$[COST].
Grupos ser formados por mais de um membro, caso contrário serão definitivamente excluídos.
Convite outros membros dentro de 48 horas.
<usetemplate canceltext="Cancelar" name="okcancelbuttons" notext="Cancelar" yestext="Criar grupo por L$100"/>
@@ -498,6 +502,9 @@ Para colocar a mídia em só uma face, selecione Selecionar face e clique na fac
<notification name="ErrorEncodingSnapshot">
Erro ao codificar a foto.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Você precisa de L$[COST] para fazer o upload deste item.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Você precisa de L$ [COST] para salvar uma foto em seu inventário. Você pode comprar L$ ou salvar a foto em seu computador.
</notification>
@@ -1729,13 +1736,16 @@ Deseja prosseguir?
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- O limite de grupos para as contas básicas é [MAX_BASIC] e para as contas [https://secondlife.com/premium/ premium],
-é [MAX_PREMIUM].
-Se você fizer downgrade de sua conta, precisará ficar abaixo do limite de grupos [MAX_BASIC] antes de entrar em mais.
-
-[https://secondlife.com/my/account/membership.php Faça o upgrade hoje!]
+ Residentes com o plano Básico podem participar de até [MAX_BASIC] grupos.
+O plano Premium permite até [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Saiba mais ou faça um upgrade]
<usetemplate name="okbutton" yestext="Fechar"/>
</notification>
+ <notification name="GroupLimitInfoPlus">
+ Residentes com o plano Básico podem participar de até [MAX_BASIC] grupos.
+O plano Premium permite até [MAX_PREMIUM]. O plano Premium Plus permite até [MAX_PREMIUM_PLUS].
+[https://secondlife.com/my/account/membership.php? Saiba mais ou faça um upgrade]
+ <usetemplate name="okbutton" yestext="Fechar"/>
+ </notification>
<notification name="KickUser">
Chutar este residente com qual mensagem?
<form name="form">
@@ -1951,6 +1961,11 @@ Isto mudará milhares de regiões e fará o spaceserver soluçar.
Ao desselecionar esta opção, você pode remover as restrições que os proprietários dos terrenos adicionaram para evitar problemas, manter a privacidade ou proteger residentes menores de idade contra conteúdo adulto. Por favor, discuta com os seus proprietários de terreno conforme necessário.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Desmarcando esta opção pode remover quaisquer ambientes personalizados que os proprietários tenham adicionado aos seus lotes..
+Por favor, discuta com os seus proprietários de terreno conforme necessário. Deseja continuar?
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
<usetemplate name="okbutton" yestext="OK"/>
@@ -2431,7 +2446,15 @@ Inclua um link para facilitar o acesso para visitantes. Teste o link na barra de
Este arquivo de ciclo de dia se refere a um arquivo de céu faltando: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- As configurações não podem ser aplicadas à região. Talvez sair e votlar à região resolva. Motivo: [FAIL_REASON]
+ As configurações não puderam ser aplicadas para a região. Motivo: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Uma textura local está em uso no rastreio [TRACK], moldura #[FRAMENO] ([FRAME]%) no campo [FIELD].
+As definições não puderam ser salvas usando as texturas locais.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Uma textura local está em uso no campo [FIELD].
+As definições não puderam ser salvas usando as texturas locais.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Impossível excluir a última chave do ciclo pois um ciclo não pode ficar vazio. Modifique a última chave em vez de tentar apagá-la, depois crie uma chave nova.
@@ -3279,6 +3302,22 @@ Para sua segurança, os SLurls serão bloqueados por alguns instantes.
Sua voz foi silenciada pelo moderador.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Infelizmente, não conseguimos obter as informações de benefícios para esta sessão. Isto não deveria ocorrer em um ambiente de produção normal. Por favor, contate o suporte. Esta sessão não funcionará normalmente e recomendamos que você reinicie.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Será feito o upload de [COUNT] itens, com um custo total de L$[COST]. Você deseja prosseguir com o upload?
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Carregar"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Não é possível fazer o upload dos arquivos selecionados de uma vez só.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Não é possível fazer o upload de alguns dos arquivos selecionados de uma vez só.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
O carregamento custa L$[PRICE]. Deseja prosseguir?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Carregar"/>
@@ -4376,4 +4415,76 @@ Tente selecionar uma quantidade menor de terreno.
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ Não pode carregar as configurações para [NAME] da base de dados.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Não foi possível aplicar aquelas configurações para o ambiente.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Não foi possível aplicar aquelas configurações para o ambiente.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Esta Região não suporta as configurações do ambiente.
+ </notification>
+ <notification label="Salvar visual" name="SaveSettingAs">
+ Salve as configurações do ambiente atual como:
+ <form name="form">
+ <input name="message">
+ [DESC] (novo)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Cancelar"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Não foi possível imporar as configurações do vento antigo [NAME] de
+[FILE].
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Não é possível definir o ambiente para este lote.
+Inserir ou selecionar um lote que você tem direitos para modificar.
+ </notification>
+ <notification name="SettingsUnsuported">
+ As configurações não são suportadas para esta região.
+Mude para uma configuração permitida para a região ou tente novamente realizar a ação.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Você está prestes a perder as alterações que você fez para este [TYPE] com o nome &quot;[NAME]&quot;.
+Tem certeza de que deseja continuar?
+ <usetemplate ignoretext="Tem certeza de que deseja perder as alterações?" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Você está prestes a remover todas as configurações aplicadas.
+Tem certeza de que deseja continuar?
+ <usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Você está prestes a remover todas as configurações de Iluminação pessoal aplicadas.
+Tem certeza de que deseja continuar?
+ <usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Você está prestes a importar configurações não transferíveis para este ciclo de dias. Caso continue, transformará as configurações que você está editando não transferível também.
+
+Esta alteração não pode ser desfeita.
+
+Tem certeza de que deseja continuar?
+ <usetemplate ignoretext="Tem certeza de que deseja tornar as configurações não transferível?" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Você não pode editar as configurações diretamente da biblioteca.
+Copie para o seu próprio inventário e tente novamente.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Encontramos problemas com essas configurações. Eles não podem ser salvos ou aplicados desta vez.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Não foi possível carregar o rastreio para [TRACK].
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Não foi possível carregar rastreio de [TRACK1] em [TRACK2].
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
index f85bb3c499..f5d513e2f6 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Tatuagem de cabeça" name="Head Tattoo" tool_tip="Clique para escolher uma foto"/>
- <texture_picker label="Tatuagem superior" name="Upper Tattoo" tool_tip="Selecione uma foto"/>
- <texture_picker label="Tatuagem inferior" name="Lower Tattoo" tool_tip="Selecione uma foto"/>
- <color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Tatuagem na cabeça" name="Head Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem parte de cima" name="Upper Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem de baixo" name="Lower Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_universal.xml b/indra/newview/skins/default/xui/pt/panel_edit_universal.xml
new file mode 100644
index 0000000000..0bcaa36f1d
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Tatuagem na cabeça" name="Head Universal Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem parte de cima" name="Upper Universal Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem de baixo" name="Lower Universal Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem de saia" name="Skirt Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem de cabelo" name="Hair Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem de olhos" name="Eyes Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem no Braço esquerdo" name="Left Arm Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Tatuagem na perna esquerdo" name="Left Leg Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Aux1 Tatuagem" name="Aux1 Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Aux2 Tatuagem" name="Aux2 Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <texture_picker label="Aux3 Tatuagem" name="Aux3 Tattoo" tool_tip="Clique para selecionar uma imagem"/>
+ <color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
index 2e3e3d6305..e8d9063206 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Editando tatuagem
</string>
+ <string name="edit_universal_title">
+ Edição Universal
+ </string>
<string name="edit_physics_title">
Editando o físico
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Tatuagem:
</string>
+ <string name="universal_desc_text">
+ Universal:
+ </string>
<string name="physics_desc_text">
Físico:
</string>
diff --git a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
deleted file mode 100644
index 442622035a..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Arraste e solte os itens aqui para prepará-los para venda na frente da sua loja"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index fce170110e..2ef01841c5 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -18,7 +18,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<string name="no_groups_msg" value="À procura de grupos interessantes? Tente fazer uma [secondlife:///app/search/groups Busca]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Clique duas vezes para abrir o mapa, shift+arraste para a visão pan)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Clique duas vezes para teletransportar, shift+arraste para a visão pan)"/>
- <string name="GroupCountWithInfo" value="Você pertence a [COUNT] grupos e pode entrar em mais [REMAINING]. [secondlife:/// Quer mais?]"/>
+ <string name="GroupCountWithInfo" value="Você faz parte de [COUNT] grupos e pode participar de mais [REMAINING]. [secondlife:/// Aumente o seu limite]"/>
<tab_container name="tabs">
<panel label="PROXIMIDADE" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<dnd_button name="minus_btn" tool_tip="Sair do grupo selecionado"/>
</panel>
<text name="groupcount">
- Você pertence a [COUNT] grupos e pode entrar em mais [REMAINING].
+ Você faz parte de [COUNT] grupos e pode participar de mais [REMAINING].
</text>
</panel>
<panel label="RECENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
index a0f4ea4ed5..d387c4c869 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
@@ -33,10 +33,10 @@ rápido
</text>
<check_box initial_value="true" label="Sempre renderizar amigos" name="AlwaysRenderFriends"/>
<button label="Exceções..." name="RenderExceptionsButton"/>
- <button label="Salvar configurações como predefinição..." name="PrefSaveButton"/>
- <button label="Carregar predefinição..." name="PrefLoadButton"/>
+ <button label="Salvar configurações como predefinição" name="PrefSaveButton" width="235" left="5"/>
+ <button label="Carregar predefinição" name="PrefLoadButton" width="130" left_pad="8"/>
min_val=&quot;0.125&quot;
- <button label="Excluir predefinição..." name="PrefDeleteButton"/>
- <button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/>
+ <button label="Excluir predefinição" name="PrefDeleteButton" width="122" left_pad="8"/>
+ <button label="Redefinir para configurações recomendadas" name="Defaults" width="255"/>
<button label="Configurações avançadas..." name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
index 03536f28c3..56fc225bc0 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
@@ -35,5 +35,5 @@
<text name="Proxy Settings:">
Configurações de proxy:
</text>
- <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy"/>
+ <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy" width="180"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_environment.xml b/indra/newview/skins/default/xui/pt/panel_region_environment.xml
index 7593c50941..f99a75d699 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Ambiente" name="panel_env_info">
- <text name="water_settings_title">
- Selecionar a Ãgua e o Céu/Configurações de Ciclo de Dias que você gostaria que todos os visitantes da sua região visse. Mais informações
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Use o padrão Second Life" name="use_sl_default_settings"/>
- <radio_item label="Use as seguintes configurações" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Configurações da água
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Selecionar uma prefefinição-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Céu / Ciclo de dias
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Céu fixo" name="my_sky_settings"/>
- <radio_item label="Ciclos de dias" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Selecionar uma prefefinição-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Selecionar uma prefefinição-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Aplicar" name="apply_btn"/>
- <button label="Cancelar" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Usar as configurações padrões
+ </string>
+ <string name="str_label_use_region">
+ Usar as configurações da região
+ </string>
+ <string name="str_altitude_desription">
+ Céu [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ Nenhum lote está selecionado. As configurações do ambiente estão desativadas.
+ </string>
+ <string name="str_cross_region">
+ As configurações do ambiente não estão disponíveis além das fronteiras da região.
+ </string>
+ <string name="str_legacy">
+ As configurações do ambiente não estão disponíveis nesta região.
+ </string>
+ <string name="str_disallowed">
+ O gerente do estado não permite alteração dos ambientes dos lotes nesta região.
+ </string>
+ <string name="str_too_small">
+ O lote deve ter no mínimo 128 metros quadrados para suportar um ambiente.
+ </string>
+ <string name="str_empty">
+ (vazio)
+ </string>
+ <string name="str_region_env">
+ (região ambiente)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Usar inventário" name="btn_select_inventory"/>
+ <button label="Customizar" name="btn_edit"/>
+ <check_box label="Os proprietários do lote podem desconsiderar o ambiente" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Céu [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Desconhecido
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Arraste uma configuração do Inventário para a caixa alvo para selecionar como o céu atual."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Céu [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Desconhecido
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Arraste uma configuração do Inventário para a caixa alvo para selecionar como o céu atual."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Céu [INDEX]
+ [ALTITUDE]m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Desconhecido
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Arraste uma configuração do Inventário para a caixa alvo para selecionar como o céu atual."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Chão
+ </text>
+ <line_editor name="edt_invname_ground">
+ Desconhecido
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Arraste uma configuração do Inventário para a caixa alvo para selecionar como o nível do chão do céu."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Ãgua
+ </text>
+ <line_editor name="edt_invname_water">
+ Desconhecido
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Arraste uma configuração do Inventário para a caixa alvo para selecionar como a água atual."/>
+ </panel>
+ <button label="Redefinir" name="btn_rst_altitudes" tool_tip="Redefinir para padrão de altitudes"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/pt/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..25c27cd6e6
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmosfera e Claridade" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/pt/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..70f814138a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Nuvens" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/pt/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..14143a928a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Densidade" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Espelhar termo exponencial:" name="rayleigh_exponential"/>
+ <slider label="Espelhar escala exponencial:" name="rayleigh_exponential_scale"/>
+ <slider label="Espelhar termo linear:" name="rayleigh_linear"/>
+ <slider label="Espelhar termo constante:" name="rayleigh_constant"/>
+ <slider label="Espelhar altitude máxima:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Mie termo exponencial:" name="mie_exponential"/>
+ <slider label="Mie escala exponencial:" name="mie_exponential_scale"/>
+ <slider label="Mie termo linear:" name="mie_linear"/>
+ <slider label="Mie termo constante:" name="mie_constant"/>
+ <slider label="Mie fator aniso:" name="mie_aniso_factor"/>
+ <slider label="Mie altitude máxima:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Absorção termo exponencial:" name="absorption_exponential"/>
+ <slider label="Absorção escala exponencial:" name="absorption_exponential_scale"/>
+ <slider label="Absorção termo linear:" name="absorption_linear"/>
+ <slider label="Absorção termo constante:" name="absorption_constant"/>
+ <slider label="Absorção altitude máxima:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/pt/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..fe6672b261
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Sol e Lua" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Exibir baliza" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Exibir baliza" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_settings_water.xml b/indra/newview/skins/default/xui/pt/panel_settings_water.xml
new file mode 100644
index 0000000000..9a6e6462bd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Ãgua" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Offset fresnel:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_tools_texture.xml b/indra/newview/skins/default/xui/pt/panel_tools_texture.xml
index 5e97eca605..4f484c5fce 100644
--- a/indra/newview/skins/default/xui/pt/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/pt/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Textura" name="Texture">
- <panel.string name="string repeats per meter">
- Repetições por metro
- </panel.string>
- <panel.string name="string repeats per face">
- Repetições por face
- </panel.string>
<text name="color label">
Cor
</text>
@@ -114,4 +108,5 @@
<spinner label="Offset horizontal" name="shinyOffsetU"/>
<spinner label="Offset vertical" name="shinyOffsetV"/>
<check_box initial_value="false" label="Alinhar planos planares" name="checkbox planar align" tool_tip="Alinhar texturas de todos os planos selecionados com o plano selecionado por último. Requer mapeamento de textura planar."/>
+ <button label="Alinhar" label_selected="Alinhar camadas de textura atual" name="button align textures" tool_tip="Alinhar camadas de textura atual"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/role_actions.xml b/indra/newview/skins/default/xui/pt/role_actions.xml
index 67ecfa0be3..e09476a83e 100644
--- a/indra/newview/skins/default/xui/pt/role_actions.xml
+++ b/indra/newview/skins/default/xui/pt/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Mudar música &amp; configurações de mídia" longdescription="Mude streaming de música e configurações de vídeo em Sobre o terreno &gt; aba Mídia." name="land change media" value="20"/>
<action description="Ativar/desativar &apos;Editar terreno&apos;" longdescription="Ative/desative &apos;Editar terreno&apos;. *AVISO* Sobre o terreno &gt; aba Opções &gt; Editar terreno permite a qualquer um alterar as formas de seu terreno, substituir e mover plantas Linden. Certifique-se de saber o que está fazendo antes de desginar esta habilidade. A edição de terreno é ativada/desativada em Sobre o terreno &gt; aba Opções." name="land edit" value="21"/>
<action description="Ativar/desativar variados Sobre o Terreno &gt; Opções de configuração" longdescription="Alterna as opções &apos;Seguro (zero danos)&apos;, &apos;Voar&apos; e autorizar outros residentes a: &apos;Editar terreno&apos;, &apos;Contruir&apos;, &apos;Criar marcos&apos; e &apos;Executar scripts&apos; nos terrenos do grupo. Clique em Sobre o terreno &gt; guia Opções." name="land options" value="22"/>
+ <action description="Modificar configurações do ambiente e ciclos de dia." longdescription="Mude as configurações de ambiente e ciclos de dia em Sobre terrenos &gt; Aba Ambiente." name="land change environment" value="46"/>
</action_set>
<action_set description="Estas habilidades incluem poderes que permitem a membros ultrapassar restrições em parcelas pertencentes ao grupo." name="Parcel Powers">
<action description="Sempre permitir &apos;Editar terreno&apos;" longdescription="Membros em uma função com esta habilidade podem editar terreno em uma parcela pertencente ao grupo, mesmo se estiver desativada em Sobre o terreno &gt; aba Opções." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index cccc70a92a..ee982b5b22 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -595,6 +595,15 @@ Aguarde um minuto antes que tentar logar-se novamente.
<string name="BUTTON_HELP">
Mostrar ajuda
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Os itens deste tipo não podem ser anexados
+às anotações desta região.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Somente itens com permissões irrestritas
+do &apos;próximo proprietário’ pode
+ser anexado às anotações.
+ </string>
<string name="Searching">
Buscando...
</string>
@@ -671,6 +680,18 @@ Aguarde um minuto antes que tentar logar-se novamente.
Erro na solicitação de upload. Acesso
http://secondlife.com/support para ajuda ao resolver este problema.
</string>
+ <string name="SettingValidationError">
+ Falha na validação para importação das configurações [NAME]
+ </string>
+ <string name="SettingImportFileError">
+ Não foi possível abrir o arquivo [FILE]
+ </string>
+ <string name="SettingParseFileError">
+ Não foi possível abrir o arquivo [FILE]
+ </string>
+ <string name="SettingTranslateError">
+ Não foi possível traduzir o vento antigo [NAME]
+ </string>
<string name="texture">
textura
</string>
@@ -746,6 +767,9 @@ http://secondlife.com/support para ajuda ao resolver este problema.
<string name="symbolic folder link">
link da pasta
</string>
+ <string name="settings blob">
+ configurações
+ </string>
<string name="mesh">
mesh
</string>
@@ -1076,6 +1100,9 @@ http://secondlife.com/support para ajuda ao resolver este problema.
<string name="ForceSitAvatar">
Forçar o avatar a sentar
</string>
+ <string name="ChangeEnvSettings">
+ Alterar sua configurações de ambiente
+ </string>
<string name="AgentNameSubst">
(Você)
</string>
@@ -1224,6 +1251,9 @@ http://secondlife.com/support para ajuda ao resolver este problema.
<string name="tattoo">
Tatuagem
</string>
+ <string name="universal">
+ Universal
+ </string>
<string name="physics">
Físico
</string>
@@ -1266,6 +1296,9 @@ http://secondlife.com/support para ajuda ao resolver este problema.
<string name="tattoo_not_worn">
Tatuagem não usada
</string>
+ <string name="universal_not_worn">
+ Universal não usado
+ </string>
<string name="physics_not_worn">
Físico não usado
</string>
@@ -1317,6 +1350,9 @@ http://secondlife.com/support para ajuda ao resolver este problema.
<string name="create_new_tattoo">
Criar nova tatuagem
</string>
+ <string name="create_new_universal">
+ Criar um novo universal
+ </string>
<string name="create_new_physics">
Criar novo físico
</string>
@@ -1560,11 +1596,14 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="MarketplaceUpdating">
atualizando...
</string>
+ <string name="UploadFeeInfo">
+ A taxa é baseada em seu nível de inscrição. Níveis mais altos possuem taxas mais baixas. [https://secondlife.com/my/account/membership.php? Saiba mais]
+ </string>
<string name="Open landmarks">
- Marcos abertos
+ Marcos em aberto
</string>
<string name="Unconstrained">
- Sem limites
+ Ilimitado
</string>
<string name="no_transfer" value="(não transferível)"/>
<string name="no_modify" value="(não modificável)"/>
@@ -2452,6 +2491,27 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="RegionSettings">
Configurações da região
</string>
+ <string name="NoEnvironmentSettings">
+ Esta Região não suporta as configurações do ambiente.
+ </string>
+ <string name="EnvironmentSun">
+ Dom
+ </string>
+ <string name="EnvironmentMoon">
+ Lua
+ </string>
+ <string name="EnvironmentBloom">
+ Florescer
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Ruído na nuvem
+ </string>
+ <string name="EnvironmentNormalMap">
+ Mapa normal
+ </string>
+ <string name="EnvironmentTransparent">
+ Transparente
+ </string>
<string name="ClassifiedClicksTxt">
Cliques: [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil
</string>
@@ -4604,6 +4664,9 @@ Denunciar abuso
<string name="New Tattoo">
Nova tatuagem
</string>
+ <string name="New Universal">
+ Novo universal
+ </string>
<string name="New Physics">
Novo físico
</string>
@@ -4730,6 +4793,15 @@ Denunciar abuso
<string name="Female - Wow">
Wow - feminino
</string>
+ <string name="New Daycycle">
+ Novo ciclo de dias
+ </string>
+ <string name="New Water">
+ Nova água
+ </string>
+ <string name="New Sky">
+ Novo céu
+ </string>
<string name="/bow">
/reverência
</string>
@@ -4902,6 +4974,9 @@ Visite http://status.secondlifegrid.net para saber se foi detectado um problema
<string name="Chat" value="Bate papo">
Bate-papo
</string>
+ <string name="BaseMembership">
+ Básico
+ </string>
<string name="DeleteItems">
Excluir itens selecionados?
</string>
@@ -5258,6 +5333,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="BeaconMedia">
Vendo balizas de mídia (branco)
</string>
+ <string name="BeaconSun">
+ Visualizando farol de direção do sol (alaranjado)
+ </string>
+ <string name="BeaconMoon">
+ Visualizando farol de direção da lua (roxo)
+ </string>
<string name="ParticleHiding">
Ocultar partículas
</string>
@@ -5285,6 +5366,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="Command_Destinations_Label">
Destinos
</string>
+ <string name="Command_Environments_Label">
+ Meus ambientes
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5378,6 +5465,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="Command_Destinations_Tooltip">
Destinos de interesse
</string>
+ <string name="Command_Environments_Tooltip">
+ Meus ambientes
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Publicar no Facebook
+ </string>
<string name="Command_Flickr_Tooltip">
Carregar no Flickr
</string>
@@ -5573,6 +5666,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="ExperiencePermission12">
aceitar automaticamente permissões de experiência
</string>
+ <string name="ExperiencePermission16">
+ forçar o avatar a sentar
+ </string>
+ <string name="ExperiencePermission17">
+ alterar sua configurações de ambiente
+ </string>
<string name="ExperiencePermissionShortUnknown">
realizar uma operação desconhecida: [Permission]
</string>
@@ -5597,6 +5696,12 @@ Tente colocar o caminho do editor entre aspas.
<string name="ExperiencePermissionShort12">
Autorização
</string>
+ <string name="ExperiencePermissionShort16">
+ Sentar
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Ambiente
+ </string>
<string name="logging_calls_disabled_log_empty">
As conversas não estão sendo registradas. Para começar a manter um registro, selecione &quot;Salvar: apenas registro&quot; ou &quot;Salvar: registro e transcrições&quot; em Preferências&gt; Bate-papo.
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_about_land.xml b/indra/newview/skins/default/xui/ru/floater_about_land.xml
index 1ae6df76d9..4848f2f7e7 100644
--- a/indra/newview/skins/default/xui/ru/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about_land.xml
@@ -338,7 +338,7 @@
<check_box label="Ð’Ñе" name="check other scripts" tool_tip="ЕÑли уÑтановлен флажок, то жители могут выполнÑть Ñкрипты на вашем учаÑтке, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ."/>
<check_box label="Группа" name="check group scripts" tool_tip="ЕÑли уÑтановлен флажок, то члены группы могут выполнÑть Ñкрипты на вашем учаÑтке, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ."/>
<check_box label="БезопаÑно (нет повреждений)" name="check safe" tool_tip="ЕÑли отмечено, то Ð·ÐµÐ¼Ð»Ñ ÑчитаетÑÑ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñной, отключены боевые повреждениÑ. ЕÑли не отмечено, то боевые Ð¿Ð¾Ð²Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ñ‹."/>
- <check_box label="Ðе толкать" name="PushRestrictCheck" tool_tip="Запрещает Ñкриптам функцию толканиÑ. Этот параметр может оказатьÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ‹Ð¼ Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð½ÐµÐ¶ÐµÐ»Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð° вашей земле."/>
+ <check_box label="Ðе толкать" name="PushRestrictCheck" left_pad="44" tool_tip="Запрещает Ñкриптам функцию толканиÑ. Этот параметр может оказатьÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ‹Ð¼ Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð½ÐµÐ¶ÐµÐ»Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð° вашей земле."/>
<check_box label="Показать меÑто в поиÑке (L$30/неделÑ)" name="ShowDirectoryCheck" tool_tip="Позволить людÑм видеть учаÑток в результатах поиÑка"/>
<combo_box name="land category">
<combo_box.item label="Ð›ÑŽÐ±Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ" name="item0"/>
@@ -360,11 +360,11 @@
Снимок:
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" left="283">
Ðватары Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков могут видеть аватары на Ñтом учаÑтке и общатьÑÑ Ñ Ð½Ð¸Ð¼Ð¸
</text>
- <check_box label="Видны аватары" name="SeeAvatarsCheck" tool_tip="Ðватары Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков Ñмогут видеть аватары на Ñтом учаÑтке и общатьÑÑ Ñ Ð½Ð¸Ð¼Ð¸ в чате, а вы также Ñможете видеть их и общатьÑÑ Ñ Ð½Ð¸Ð¼Ð¸."/>
- <text name="landing_point">
+ <check_box label="Видны аватары" left="262" name="SeeAvatarsCheck" tool_tip="Ðватары Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков Ñмогут видеть аватары на Ñтом учаÑтке и общатьÑÑ Ñ Ð½Ð¸Ð¼Ð¸ в чате, а вы также Ñможете видеть их и общатьÑÑ Ñ Ð½Ð¸Ð¼Ð¸."/>
+ <text name="landing_point" width="225">
В точку телепортации: [LANDING]
</text>
<button label="Задать" label_selected="Задать" name="Set" tool_tip="УÑтановить точку телепортации, в которую будут прибывать поÑетители, СтавитÑÑ Ð² меÑте вашего аватара на Ñтом учаÑтке."/>
@@ -372,7 +372,7 @@
<text name="Teleport Routing: ">
Вариант телепортации:
</text>
- <combo_box name="landing type" tool_tip="Вариант телепортации – выберите, каким образом будет производитьÑÑ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° вашу землю">
+ <combo_box name="landing type" width="150" tool_tip="Вариант телепортации – выберите, каким образом будет производитьÑÑ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ð° вашу землю">
<combo_box.item label="Ð’ черном ÑпиÑке" name="Blocked"/>
<combo_box.item label="В точку телепортации" name="LandingPoint"/>
<combo_box.item label="Ð’ любое меÑто" name="Anywhere"/>
@@ -439,7 +439,7 @@
<panel.string name="estate_override">
ЧаÑть Ñтих параметров уÑтановлена на уровне землевладениÑ
</panel.string>
- <check_box label="ДоÑтуп открыт Ð´Ð»Ñ Ð²Ñех (При ÑнÑÑ‚Ð¸Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ Ñоздана запиÑÑŒ в Ñтроке запрета)" name="public_access"/>
+ <check_box label="ДоÑтуп открыт Ð´Ð»Ñ Ð²Ñех" tool_tip="При ÑнÑÑ‚Ð¸Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ Ñоздана запиÑÑŒ в Ñтроке запрета" name="public_access"/>
<check_box label="Должен быть 18 и Ñтарше [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ДоÑтуп к Ñтому учаÑтку имеют только жители 18 лет и Ñтарше. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
<check_box label="Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ платежах должна быть в файле [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому учаÑтку у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть зарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
<check_box label="Разрешить группе [GROUP] без вÑÑких ограничений" name="GroupCheck" tool_tip="Группа уÑтанавливаетÑÑ Ð½Ð° оÑновной вкладке."/>
@@ -474,5 +474,6 @@
</panel>
</panel>
<panel label="ПРИКЛЮЧЕÐИЯ" name="land_experiences_panel"/>
+ <panel label="ОКРУЖÐЮЩÐЯ СРЕДÐ" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_adjust_environment.xml b/indra/newview/skins/default/xui/ru/floater_adjust_environment.xml
new file mode 100644
index 0000000000..85809966e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Личное оÑвещение">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="СброÑ" name="btn_reset" tool_tip="Закрыть и ÑброÑить в общую Ñреду"/>
+ <text name="cloud_map_label">
+ Изображение облака:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Солнце:
+ </text>
+ <check_box label="Показать метку" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="Показать метку" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_beacons.xml b/indra/newview/skins/default/xui/ru/floater_beacons.xml
index 38d257ff81..9d706a7c5d 100644
--- a/indra/newview/skins/default/xui/ru/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/ru/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="ИÑточники звука" name="sounds"/>
<check_box label="ИÑточники чаÑтиц" name="particles"/>
<check_box label="ИÑточники медиа" name="moapbeacon"/>
+ <check_box label="Солнце" name="sun"/>
+ <check_box label="Луна" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml b/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
index 55b0e0c3bd..f5115a161d 100644
--- a/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
@@ -21,6 +21,7 @@
<icon name="icon_script" tool_tip="Скрипты"/>
<icon name="icon_sound" tool_tip="Звуки"/>
<icon name="icon_texture" tool_tip="ТекÑтуры"/>
+ <icon name="icon_setting" tool_tip="ÐаÑтройки окружающей Ñреды"/>
<button label="√ Ð’Ñе" name="check_all"/>
<button label="ОчиÑтить" label_selected="Ðет" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
index 87e8bd524e..ef55ce58d4 100644
--- a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="ПриобреÑти" name="buy_btn"/>
<button label="Отмена" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
ÐÐµÐ»ÑŒÐ·Ñ ÐºÑƒÐ¿Ð¸Ñ‚ÑŒ
- </text>
- <button label="Продолжить в Интернете" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml
deleted file mode 100644
index 1ae278f03b..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="УДÐЛЕÐИЕ ÐÐСТРОЙКИ СРЕДЫ">
- <string name="title_water">
- Удалить наÑтройку воды
- </string>
- <string name="title_sky">
- Удалить наÑтройку неба
- </string>
- <string name="title_day_cycle">
- Удалить Ñуточный цикл
- </string>
- <string name="label_water">
- ÐаÑтройка:
- </string>
- <string name="label_sky">
- ÐаÑтройка:
- </string>
- <string name="label_day_cycle">
- Суточный цикл:
- </string>
- <string name="msg_confirm_deletion">
- ДейÑтвительно удалить выбранную наÑтройку?
- </string>
- <string name="msg_sky_is_referenced">
- ÐÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ наÑтройку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¸ÑпользуетÑÑ Ð² некоторых Ñуточных циклах.
- </string>
- <string name="combo_label">
- -Выбор наÑтройки-
- </string>
- <text name="label">
- ÐаÑтройка:
- </text>
- <button label="Удалить" name="delete"/>
- <button label="Отмена" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/ru/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..ba01b13a82
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Изменить Ñуточный цикл">
+ <string name="title_new">
+ Создать новый Ñуточный цикл
+ </string>
+ <string name="title_edit">
+ Изменить Ñуточный цикл
+ </string>
+ <string name="hint_new">
+ Введите Ð¸Ð¼Ñ Ñуточного цикла, задайте его параметры Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñлементов ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ нажмите кнопку «Сохранить».
+ </string>
+ <string name="hint_edit">
+ Чтобы изменить Ñуточный цикл, задайте его параметры Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñлементов ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¸Ð¶Ðµ и нажмите кнопку «Сохранить».
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Ðебо [ALT]
+ </string>
+ <string name="sky_label">
+ Ðебо
+ </string>
+ <string name="water_label">
+ Вода
+ </string>
+ <string name="commit_parcel">
+ Применить к учаÑтку
+ </string>
+ <string name="commit_region">
+ Применить к региону
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Ðазвание Ñуточного цикла:
+ </text>
+ <button label="Импортировать" name="btn_import" tool_tip="Импортировать уÑтаревшие наÑтройки Ñ Ð´Ð¸Ñка."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Ðебо 4" name="sky4_track"/>
+ <button label="Ðебо 3" name="sky3_track"/>
+ <button label="Ðебо 2" name="sky2_track"/>
+ <button label="Уровень земли" name="sky1_track"/>
+ <button label="Вода" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Клонировать режим Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·" name="copy_track"/>
+ <button label="Загрузить режим Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·" name="load_track"/>
+ <button label="ОчиÑтить режим редактированиÑ" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Шаг назад"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="Шаг вперед"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="Добавить [FRAME]" name="add_frame"/>
+ <button label="Загрузить [FRAME]" name="btn_load_frame"/>
+ <button label="Удалить [FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Выбрать ключевой фрейм на временной шкале выше Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Вода" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="ÐтмоÑфера и оÑвещение" name="atmosphere_panel"/>
+ <panel label="Облака" name="clouds_panel"/>
+ <panel label="Солнце и луна" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Сохранить" name="save_btn"/>
+ <button label="Отмена" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/ru/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..b5f1a1ced2
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="ФикÑÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñреда">
+ <string name="edit_sky">
+ Редактировать наÑтройки неба:
+ </string>
+ <string name="edit_water">
+ Редактировать наÑтройки воды:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Загрузить" name="btn_load" tool_tip="Загрузить наÑтройки из инвентарного ÑпиÑка"/>
+ <button label="Импортировать" name="btn_import" tool_tip="Импортировать уÑтаревшие наÑтройки Ñ Ð´Ð¸Ñка."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Сохранить" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="Отмена" name="btn_cancel" tool_tip="ВернутьÑÑ Ðº поÑледней Ñохраненной верÑии"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
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 ce6b89cb82..7c1d3b52c5 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
@@ -12,6 +12,7 @@
<check_box label="Звуки" name="check_sound"/>
<check_box label="ТекÑтуры" name="check_texture"/>
<check_box label="Снимки" name="check_snapshot"/>
+ <check_box label="ÐаÑтройки" name="check_settings"/>
<button label="Ð’Ñе" label_selected="Ð’Ñе" name="All"/>
<button label="Ðет" label_selected="Ðет" name="None"/>
<check_box label="Ð’Ñегда показывать папки" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
deleted file mode 100644
index 1d3ff3f5ed..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="ТОРГОВЫЕ ИСХОДЯЩИЕ">
- <string name="OutboxFolderCount1">
- 1 папка
- </string>
- <string name="OutboxFolderCountN">
- [NUM] папки
- </string>
- <string name="OutboxImporting">
- Отправка папок....
- </string>
- <string name="OutboxInitializing">
- ИнициализациÑ...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Загрузка...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- ПеретаÑкивайте предметы Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð°Ð¿Ð¾Ðº
- </text>
- </panel>
- <button label="Отправить в торговый центр" name="outbox_import_btn" tool_tip="Ð’Ñ‹Ñтавить на витрину моего магазина"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_my_environments.xml b/indra/newview/skins/default/xui/ru/floater_my_environments.xml
new file mode 100644
index 0000000000..ba31600df7
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="МеÑта" name="my_environments" title="МОЯ ОКРУЖÐЮЩÐЯ СРЕДÐ">
+ <layout_stack>
+ <layout_panel label="Фильтры" name="filter_panel">
+ <check_box label="Дни" name="chk_days"/>
+ <check_box label="ÐебеÑа" name="chk_skies"/>
+ <check_box label="Вода" name="chk_water"/>
+ <filter_editor label="Фильтр окружающей Ñреды" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="ÐžÐºÑ€ÑƒÐ¶Ð°ÑŽÑ‰Ð°Ñ Ñреда" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Показать вÑе папки" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Дополнительные параметры"/>
+ <menu_button name="btn_newsettings" tool_tip="Создать новую наÑтройку"/>
+ <button name="btn_del" tool_tip="Удалить выбранную вещь"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_perms_default.xml b/indra/newview/skins/default/xui/ru/floater_perms_default.xml
index a33c6b40b6..2a239c07c4 100644
--- a/indra/newview/skins/default/xui/ru/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/ru/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Задайте Ñтандартные Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð´ÐµÐ¶Ð´Ñ‹ или чаÑтей тела">
ÐоÑимые вещи
</text>
+ <text name="label_13" tool_tip="Задать Ñтандартные разрешениÑ, когда будут Ñозданы наÑтройки Ñреды">
+ ÐаÑтройки
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="OK" label_selected="OK" name="ok"/>
<button label="Отмена" label_selected="Отмена" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_pick_track.xml b/indra/newview/skins/default/xui/ru/floater_pick_track.xml
new file mode 100644
index 0000000000..7588e1759c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="ВЫБРÐТЬ: РЕЖИМ РЕДÐКТИРОВÐÐИЯ">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Выбрать иÑточник неба:
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Ðебо4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Ðебо3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Ðебо2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="ЗемлÑ" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Отмена" label_selected="Отмена" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/ru/floater_preferences_graphics_advanced.xml
index fc6b6a173e..84e1ff15a0 100644
--- a/indra/newview/skins/default/xui/ru/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="ПрозрачноÑть воды" name="TransparentWater"/>
<check_box initial_value="true" label="РельефноÑть и ÑиÑние" name="BumpShiny"/>
<check_box initial_value="true" label="Локальный Ñвет" name="LocalLights"/>
- <check_box initial_value="true" label="Базовые шейдеры" name="BasicShaders" tool_tip="Отключение Ñтого параметра может предотвратить завиÑание некоторых видеокарт"/>
<slider label="Ландшафт:" name="TerrainDetail"/>
<text name="TerrainDetailText">
ÐизкаÑ
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 c9cb87282a..46d2a37503 100644
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
@@ -10,12 +10,12 @@
ОпиÑание:
</text>
<text name="dimensions">
- [WIDTH]x[HEIGHT] пикÑелей
+ [WIDTH]пикÑелей x [HEIGHT]пикÑелей
</text>
<text name="aspect_ratio">
- Соотношение Ñторон
+ ПроÑмотр Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñоотношением Ñторон
</text>
- <combo_box name="combo_aspect_ratio" tool_tip="ПроÑмотр Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼ Ñоотношением Ñторон">
+ <combo_box name="combo_aspect_ratio" tool_tip="ПроÑмотр Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ„Ð¸ÐºÑированным Ñоотношением Ñторон">
<combo_item name="Unconstrained">
Без ограничениÑ
</combo_item>
@@ -42,6 +42,6 @@
</combo_item>
</combo_box>
<button label="OK" name="Keep"/>
- <button label="Удалить" name="Discard"/>
+ <button label="Отменить" name="Discard"/>
<button label="Сохранить как" name="save_tex_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_settings_picker.xml b/indra/newview/skins/default/xui/ru/floater_settings_picker.xml
new file mode 100644
index 0000000000..84f0e303fc
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="ВЫБРÐТЬ: ÐÐСТРОЙКИ">
+ <floater.string name="pick title">
+ Выбрать:
+ </floater.string>
+ <floater.string name="pick_track">
+ ВЫБРÐТЬ РЕЖИМ РЕДÐКТИРОВÐÐИЯ
+ </floater.string>
+ <floater.string name="pick_settings">
+ ВЫБРÐТЬ ÐÐСТРОЙКИ
+ </floater.string>
+ <floater.string name="track_water">
+ Вода
+ </floater.string>
+ <floater.string name="track_ground">
+ ЗемлÑ
+ </floater.string>
+ <floater.string name="track_sky">
+ Ðебо[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Фильтровать текÑтуры" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="OK" label_selected="OK" name="btn_select"/>
+ <button label="Отмена" label_selected="Отмена" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
index c9e117362f..d4323e5c34 100644
--- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
@@ -9,17 +9,13 @@
<text name="Multiple">
ÐеÑколько текÑтур
</text>
- <radio_group name="mode_selection">
- <radio_item label="Инвентарь" name="inventory" value="0"/>
- <radio_item label="Локально" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Размер: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Инвентарь" name="inventory" value="0"/>
+ <combo_box.item label="Локально" name="local" value="1"/>
+ </combo_box>
<button label="По умолчанию" label_selected="По умолчанию" name="Default"/>
<button label="ОчиÑтить" label_selected="ОчиÑтить" name="Blank"/>
<button label="Ðет" label_selected="Ðет" name="None"/>
- <check_box initial_value="true" label="Применить ÑейчаÑ" name="apply_immediate_check"/>
<text name="preview_disabled" value="ПроÑмотр отключен"/>
<filter_editor label="Фильтровать текÑтуры" name="inventory search editor"/>
<check_box initial_value="false" label="Показывать папки" name="show_folders_check"/>
@@ -30,6 +26,22 @@
<column label="ИмÑ" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Выбрать фикÑированную текÑтуру">
+ <combo_box.item label="Ðикакой" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Скрыть регион базовой Ñетки" name="hide_base_mesh_region"/>
<button label="ОК" label_selected="ОК" name="Select"/>
<button label="Отмена" label_selected="Отмена" name="Cancel"/>
+ <check_box initial_value="true" label="Применить ÑейчаÑ" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
index 72d1bc52b5..bc60188e2d 100644
--- a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="КоÑнутьÑÑ" name="touch_attach" />
+ <menu_item_call label="Изменить" name="edit_item" />
<menu_item_call label="ОтÑоединить" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml
index 3404ae29a3..0f63324e90 100644
--- a/indra/newview/skins/default/xui/ru/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="Ðктивировать" name="Marketplace Activate"/>
<menu_item_call label="Деактивировать" name="Marketplace Deactivate"/>
<menu_item_call label="ПоделитьÑÑ" name="Share"/>
- <menu_item_call label="Купить" name="Task Buy"/>
<menu_item_call label="Открыть" name="Task Open"/>
<menu_item_call label="ВоÑпроизвеÑти" name="Task Play"/>
<menu_item_call label="СвойÑтва" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Ðовые труÑÑ‹" name="New Underpants"/>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð°Ð»ÑŒÑ„Ð°-маÑка" name="New Alpha Mask"/>
<menu_item_call label="Ðовое тату" name="New Tattoo"/>
+ <menu_item_call label="Ðовые универÑальные" name="New Universal"/>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ°" name="New Physics"/>
</menu>
<menu label="Ðовые чаÑти тела" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Ðовые волоÑÑ‹" name="New Hair"/>
<menu_item_call label="Ðовые глаза" name="New Eyes"/>
</menu>
+ <menu label="Ðовые наÑтройки" name="New Settings">
+ <menu_item_call label="Ðовое небо" name="New Sky"/>
+ <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð²Ð¾Ð´Ð°" name="New Water"/>
+ <menu_item_call label="Ðовый Ñуточный цикл" name="New Day Cycle"/>
+ </menu>
<menu label="ИÑпользовать по умолчанию длÑ" name="upload_def">
<menu_item_call label="Переданные изображениÑ" name="Image uploads"/>
<menu_item_call label="Переданные звуки" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Ðадеть" name="Wearable And Object Wear"/>
<menu label="ПриÑоединить к" name="Attach To"/>
<menu label="ПриÑоединить к данным в игре" name="Attach To HUD"/>
+ <menu_item_call label="КоÑнутьÑÑ" name="Attachment Touch" />
<menu_item_call label="Изменить" name="Wearable Edit"/>
<menu_item_call label="Добавить" name="Wearable Add"/>
<menu_item_call label="СнÑть" name="Take Off"/>
+ <menu_item_call label="Применить только к Ñебе" name="Settings Apply Local"/>
+ <menu_item_call label="Применить к учаÑтку" name="Settings Apply Parcel"/>
<menu_item_call label="Копировать в ÑпиÑки товаров торгового центра" name="Marketplace Copy"/>
<menu_item_call label="ПеремеÑтить в ÑпиÑки товаров торгового центра" name="Marketplace Move"/>
<menu_item_call label="- нет дейÑтвий -" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory_add.xml b/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
index 9a240c653e..94ec61af90 100644
--- a/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Звук (L$[COST])..." name="Upload Sound"/>
<menu_item_call label="ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ (L$[COST])..." name="Upload Animation"/>
<menu_item_call label="Модель..." name="Upload Model"/>
- <menu_item_call label="МаÑтер моделированиÑ..." name="Upload Model Wizard"/>
<menu_item_call label="Ð’Ñе Ñразу (L$[COST] за файл)..." name="Bulk Upload"/>
- <menu_item_call label="УÑтановить Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° передачу по умолчанию" name="perm prefs"/>
</menu>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°" name="New Folder"/>
<menu_item_call label="Ðовый Ñкрипт" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Ðовые труÑÑ‹" name="New Underpants"/>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð°Ð»ÑŒÑ„Ð°-маÑка" name="New Alpha"/>
<menu_item_call label="Ðовое тату" name="New Tattoo"/>
+ <menu_item_call label="Ðовые универÑальные" name="New Universal"/>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ°" name="New Physics"/>
</menu>
<menu label="Ðовые чаÑти тела" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Ðовые волоÑÑ‹" name="New Hair"/>
<menu_item_call label="Ðовые глаза" name="New Eyes"/>
</menu>
+ <menu label="Ðовые наÑтройки" name="New Settings">
+ <menu_item_call label="Ðовое небо" name="New Sky"/>
+ <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð²Ð¾Ð´Ð°" name="New Water"/>
+ <menu_item_call label="Ðовый Ñуточный цикл" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
index 24d780ba1c..1d883220e8 100644
--- a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð°Ð»ÑŒÑ„Ð°-маÑка" name="New Alpha"/>
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ°" name="New Physics"/>
<menu_item_call label="Ðовое тату" name="New Tattoo"/>
+ <menu_item_call label="Ðовые универÑальные" name="New Universal"/>
</menu>
<menu label="Ðовые чаÑти тела" name="New Body Parts">
<menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ñ„Ð¸Ð³ÑƒÑ€Ð°" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_save_settings.xml b/indra/newview/skins/default/xui/ru/menu_save_settings.xml
new file mode 100644
index 0000000000..9a9c796cf6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Сохранить" name="save_settings"/>
+ <menu_item_check label="Сохранить как" name="save_as_new_settings"/>
+ <menu_item_check label="Подтвердить" name="commit_changes"/>
+ <menu_item_check label="Применить только к Ñебе" name="apply_local"/>
+ <menu_item_check label="Применить к учаÑтку" name="apply_parcel"/>
+ <menu_item_check label="Применить к региону" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_settings_add.xml b/indra/newview/skins/default/xui/ru/menu_settings_add.xml
new file mode 100644
index 0000000000..a3ef976424
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Ðовое небо" name="New Sky"/>
+ <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð²Ð¾Ð´Ð°" name="New Water"/>
+ <menu_item_call label="Ðовый Ñуточный цикл" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_settings_gear.xml b/indra/newview/skins/default/xui/ru/menu_settings_gear.xml
new file mode 100644
index 0000000000..9d17424b85
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Редактировать" name="edit_settings"/>
+ <menu_item_call label="Применить только к Ñебе" name="Settings Apply Local"/>
+ <menu_item_call label="Применить к учаÑтку" name="Settings Apply Parcel"/>
+ <menu_item_call label="Применить к региону" name="Settings Apply Region"/>
+ <menu_item_call label="Копировать" name="copy_settings"/>
+ <menu_item_call label="Ð’Ñтавить" name="paste_settings"/>
+ <menu_item_call label="Копировать UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index 876972ba24..8361464f4c 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -77,30 +77,15 @@
<menu_item_check label="СвойÑтва учаÑтка" name="Parcel Properties"/>
<menu_item_check label="Меню «Дополнительно»" name="Show Advanced Menu"/>
</menu>
- <menu label="Солнце" name="Sun">
+ <menu label="ÐžÐºÑ€ÑƒÐ¶Ð°ÑŽÑ‰Ð°Ñ Ñреда" name="Environment">
<menu_item_check label="ВоÑход" name="Sunrise"/>
<menu_item_check label="Полдень" name="Noon"/>
<menu_item_check label="Закат" name="Sunset"/>
<menu_item_check label="Полночь" name="Midnight"/>
- <menu_item_check label="ИÑпользовать наÑтройки региона" name="Use Region Settings"/>
- </menu>
- <menu label="Редактор Ñреды" name="Environment Editor">
- <menu_item_call label="ÐаÑтройки Ñреды..." name="Environment Settings"/>
- <menu label="ÐаÑтройки воды" name="Water Presets">
- <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð½Ð°Ñтройка..." name="new_water_preset"/>
- <menu_item_call label="Изменить наÑтройку..." name="edit_water_preset"/>
- <menu_item_call label="Удалить наÑтройку..." name="delete_water_preset"/>
- </menu>
- <menu label="ÐаÑтройки неба" name="Sky Presets">
- <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð½Ð°Ñтройка..." name="new_sky_preset"/>
- <menu_item_call label="Изменить наÑтройку..." name="edit_sky_preset"/>
- <menu_item_call label="Удалить наÑтройку..." name="delete_sky_preset"/>
- </menu>
- <menu label="Суточные наÑтройки" name="Day Presets">
- <menu_item_call label="ÐÐ¾Ð²Ð°Ñ Ð½Ð°Ñтройка..." name="new_day_preset"/>
- <menu_item_call label="Изменить наÑтройку..." name="edit_day_preset"/>
- <menu_item_call label="Удалить наÑтройку..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="ИÑпользование окружающей Ñреды" name="Use Shared Environment"/>
+ <menu_item_call label="ÐœÐ¾Ñ Ñреда…" name="my_environs"/>
+ <menu_item_call label="Личное оÑвещение..." name="adjustment_tool"/>
+ <menu_item_check label="ПриоÑтановить движение облаков" name="pause_clouds"/>
</menu>
</menu>
<menu label="СтроительÑтво" name="BuildTools">
@@ -343,6 +328,9 @@
<menu_item_check label="ÐвтоматичеÑкие альфа-маÑки (не отложенные)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="ТекÑтуры анимаций" name="Animation Textures"/>
<menu_item_check label="Отключить текÑтуры" name="Disable Textures"/>
+ <menu_item_check label="Отключить окружающую Ñреду" name="Disable Ambient"/>
+ <menu_item_check label="Отключить Ñолнечный Ñвет" name="Disable Sunlight"/>
+ <menu_item_check label="Отключить локальный Ñвет" name="Disable Local Lights"/>
<menu_item_check label="ТекÑтуры в полном разрешении" name="Rull Res Textures"/>
<menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных иÑточников Ñвета" name="Render Attached Lights"/>
<menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных чаÑтиц" name="Render Attached Particles"/>
@@ -480,6 +468,7 @@
<menu_item_call label="Юбка" name="Skirt"/>
<menu_item_call label="Ðльфа" name="Alpha"/>
<menu_item_call label="Тату" name="Tattoo"/>
+ <menu_item_call label="УниверÑальные" name="Universal"/>
<menu_item_call label="Физика" name="Physics"/>
<menu_item_call label="Ð’ÑÑ Ð¾Ð´ÐµÐ¶Ð´Ð°" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
index 2832e17b7d..caef7db458 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="Заменить" name="wear_replace"/>
<menu_item_call label="Ðадеть" name="wear_wear"/>
<menu_item_call label="Добавить" name="wear_add"/>
+ <menu_item_call label="КоÑнутьÑÑ" name="touch" />
<menu_item_call label="СнÑть / отÑоединить" name="take_off_or_detach"/>
<menu_item_call label="ОтÑоединить" name="detach"/>
<context_menu label="ПриÑоединить" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
index c2351fbfff..01491b9694 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Изменить коÑтюм" name="edit"/>
+ <menu_item_call label="КоÑнутьÑÑ" name="touch"/>
+ <menu_item_call label="Изменить" name="edit_item"/>
+ <menu_item_call label="Изменить коÑтюм" name="edit_outfit"/>
<menu_item_call label="СнÑть" name="takeoff"/>
<menu_item_call label="Копировать ÑпиÑок коÑтюмов в буфер обмена" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
index 1e32090c2a..e68b67bb33 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="КоÑнутьÑÑ" name="touch_attach"/>
<menu_item_call label="СнÑть" name="take_off"/>
<menu_item_call label="ОтÑоединить" name="detach"/>
- <menu_item_call label="Изменить коÑтюм" name="edit"/>
+ <menu_item_call label="Изменить коÑтюм" name="edit_outfit"/>
<menu_item_call label="Изменить" name="edit_item"/>
<menu_item_call label="Показать оригинал" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 1e4f9e9abb..bfcda798be 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -266,6 +266,10 @@
Отобрать у выбранных жителей права на изменение?
<usetemplate name="okcancelbuttons" notext="Ðет" yestext="Да"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ Ðазвание группы может Ñодержать от [MIN_LEN] до [MAX_LEN] Ñимволов.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UnableToCreateGroup">
Ðевозможно Ñоздать группу.
[MESSAGE]
@@ -360,7 +364,7 @@
У Ð²Ð°Ñ Ð½Ðµ хватает L$ Ð´Ð»Ñ Ð²ÑтуплениÑ.
</notification>
<notification name="CreateGroupCost">
- Создание Ñтой группы Ñтоит L$100.
+ Создание Ñтой группы Ñтоит L$[COST].
Ð’ группе должно быть более одного учаÑтника, иначе она будет удалена.
ПриглаÑите учаÑтников в ближайшие 48 чаÑов.
<usetemplate canceltext="Отмена" name="okcancelbuttons" notext="Отмена" yestext="Создать группу за L$100"/>
@@ -500,6 +504,9 @@
<notification name="ErrorEncodingSnapshot">
Ошибка при кодировке Ñнимка.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Чтобы загрузить Ñтот предмет, вам нужно L$[COST].
+ </notification>
<notification name="ErrorPhotoCannotAfford">
ТребуетÑÑ L$[COST] Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ‚Ð¾ в вашем инвентаре. Купите L$ или Ñохраните фото на компьютере.
</notification>
@@ -1612,22 +1619,22 @@
[DOWNLOAD_PATH].
</notification>
<notification name="RequiredUpdate">
- Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° необходима верÑÐ¸Ñ \[VERSION].
+ Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° необходима верÑÐ¸Ñ [VERSION].
Скачайте обновление Ñ Ð²ÐµÐ±-Ñайта https://secondlife.com/support/downloads/
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="PauseForUpdate">
- Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° необходима верÑÐ¸Ñ \[VERSION].
+ Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° необходима верÑÐ¸Ñ [VERSION].
Ðажмите OK Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ и уÑтановки.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="OptionalUpdateReady">
- ВерÑÐ¸Ñ \[VERSION] загружена и готова к уÑтановке.
+ ВерÑÐ¸Ñ [VERSION] загружена и готова к уÑтановке.
Ðажмите OK Ð´Ð»Ñ ÑƒÑтановки.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="PromptOptionalUpdate">
- ВерÑÐ¸Ñ \[VERSION] загружена и готова к уÑтановке.
+ ВерÑÐ¸Ñ [VERSION] загружена и готова к уÑтановке.
Продолжить?
<usetemplate canceltext="Ðе ÑейчаÑ" name="yesnocancelbuttons" notext="ПропуÑтить" yestext="УÑтановить"/>
</notification>
@@ -1738,11 +1745,14 @@
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="GroupLimitInfo">
- МакÑимальное чиÑло групп Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ аккаунта ÑоÑтавлÑет [MAX_BASIC],
-а Ð´Ð»Ñ [https://secondlife.com/premium/ премиум]-аккаунта – [MAX_PREMIUM].
-Чтобы вÑтупать в новые группы поÑле возврата к базовому аккаунту, вам придетÑÑ Ð²Ñ‹Ð¹Ñ‚Ð¸ из чаÑти групп, чтобы их общее чиÑло было меньше [MAX_BASIC].
-
-[https://secondlife.com/my/account/membership.php Перейдите на премиум-членÑтво!]
+ Резиденты Ñ Ð‘Ð°Ð·Ð¾Ð²Ñ‹Ð¼ аккаунтом могут приÑоединитьÑÑ Ðº [MAX_BASIC] группам.
+Премиум аккаунт разрешает до [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Узнайте больше или раÑширьте Ñвой аккаунт]
+ <usetemplate name="okbutton" yestext="Закрыть"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ Резиденты Ñ Ð‘Ð°Ð·Ð¾Ð²Ñ‹Ð¼ аккаунтом могут приÑоединитьÑÑ Ðº [MAX_BASIC] группам.
+Премиум аккаунт разрешает до [MAX_PREMIUM]. Премиум ÐŸÐ»ÑŽÑ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚ разрешает до [MAX_PREMIUM_PLUS].
+[https://secondlife.com/my/account/membership.php? Узнайте больше или раÑширьте Ñвой аккаунт]
<usetemplate name="okbutton" yestext="Закрыть"/>
</notification>
<notification name="KickUser">
@@ -1959,6 +1969,11 @@
При ÑнÑтии Ñтой опции вы можете удалить ограничениÑ, которые владельцы учаÑтка добавили Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð²Ð¾ÐºÐ°Ñ†Ð¸Ð¾Ð½Ð½Ñ‹Ñ… Ñообщений, ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ñти и защиты неÑовершеннолетных жителей от материала Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых. При необходимоÑти обÑудите Ñо Ñвоими владельцами учаÑтков.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ При ÑнÑтии Ñтой опции вы можете удалить пользовательÑкую Ñреду, которую владельцы учаÑтка добавили Ð´Ð»Ñ Ñвоих учаÑтков. При необходимоÑти обÑудите Ñо Ñвоими владельцами учаÑтков.
+Вы хотите продолжить?
+ <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
<usetemplate name="okbutton" yestext="OK"/>
@@ -2438,7 +2453,15 @@
Этот файл Ñуточного цикла ÑÑылаетÑÑ Ð½Ð° отÑутÑтвующий файл неба: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- Ðе удалоÑÑŒ применить наÑтройки к региону. Попробуйте покинуть регион, а затем вернутьÑÑ Ð² него. Причина неполадки: [FAIL_REASON]
+ К Ñожалению наÑтройки не применимы к Ñтому региону. Причина: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ МеÑÑ‚Ð½Ð°Ñ Ñ‚ÐµÐºÑтура иÑпользуетÑÑ Ð² режиме Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ [TRACK], â„– фрейма [FRAMENO] ([FRAMENO]%) на поле [FIELD].
+ÐаÑтройки невозможно Ñохранить Ñ Ð¸Ñпользованием меÑтных текÑтур.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ МеÑÑ‚Ð½Ð°Ñ Ñ‚ÐµÐºÑтура иÑпользуетÑÑ Ð½Ð° поле [FIELD].
+ÐаÑтройки невозможно Ñохранить Ñ Ð¸Ñпользованием меÑтных текÑтур.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Ðевозможно удалить поÑледний ключ в Ñтом Ñуточном цикле: пуÑтой Ñуточный цикл не разрешен. Следует изменить поÑледний оÑтавшийÑÑ ÐºÐ»ÑŽÑ‡, а не удалÑть его и Ñоздавать новый.
@@ -3290,6 +3313,22 @@
Ваш Ð³Ð¾Ð»Ð¾Ñ Ð·Ð°Ð³Ð»ÑƒÑˆÐµÐ½ модератором.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ К Ñожалению, в Ñтой ÑеÑÑии мы не Ñмогли получить информацию о преимущеÑтвах аккаунта. Такое не должно проиÑходить в нормально работающей Ñреде. ПожалуйÑта, ÑвÑжитеÑÑŒ Ñо Ñлужбой поддержки. Эта ÑеÑÑÐ¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÐµÑ‚ некорректно, поÑтому мы рекомендуем вам перезапуÑтить программу.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Этим дейÑтвием загружаетÑÑ [COUNT] предметов на общую ÑтоимоÑть L$[COST]. Ð’Ñ‹ хотите продолжить загрузку?
+ <usetemplate name="okcancelbuttons" notext="Отмена" yestext="Загрузить"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Выбранные файлы не могут быть загружены группой.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Ðекоторые из выбранных файлов не могут быть загружены группой.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="UploadCostConfirmation">
Эта передача будет Ñтоить L$[PRICE]. Продолжить передачу?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="Передать"/>
@@ -4389,4 +4428,76 @@
[REASON]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
+ <notification name="FailedToFindSettings">
+ Ðе удалоÑÑŒ загрузить наÑтройки Ð´Ð»Ñ [NAME] из базы данных.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Ðевозможно применить Ñти наÑтройки Ð´Ð»Ñ Ñтой Ñреды.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Ðевозможно применить Ñти наÑтройки Ð´Ð»Ñ Ñтой Ñреды.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Этот регион не поддерживает наÑтройки окружающей Ñреды.
+ </notification>
+ <notification label="Сохранить коÑтюм" name="SaveSettingAs">
+ Сохранить текущие наÑтройки как:
+ <form name="form">
+ <input name="message">
+ [DESC] (новый)
+ </input>
+ <button name="OK" text="OK"/>
+ <button name="Cancel" text="Отмена"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Ðевозможно импортировать уÑтаревшие уÑтановки [NAME] Ð´Ð»Ñ Ñффекта Windlight из
+[FILE].
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Ðевозможно уÑтановить наÑтройки Ñреды Ð´Ð»Ñ Ñтого учаÑтка.
+ВвеÑти или выбрать учаÑток, который вы можете модифицировать.
+ </notification>
+ <notification name="SettingsUnsuported">
+ ÐаÑтройки окружающей Ñреды не поддерживаютÑÑ Ð² Ñтом регионе.
+Перейдите в регион Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ð¼Ð¸ наÑтройками и повторите дейÑтвие.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ Ð’Ñ‹ потерÑете изменениÑ, внеÑенные в Ñтот [TYPE] под именем &quot;[NAME]&quot;.
+Вы уверены, что хотите продолжить?
+ <usetemplate ignoretext="Ð’Ñ‹ уверены, что хотите Ñделать наÑтройки непереноÑимыми?" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Ð’Ñ‹ ÑобираетеÑÑŒ удалить вÑе примененные наÑтройки.
+Вы уверены, что хотите продолжить?
+ <usetemplate name="okcancelbuttons" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Ð’Ñ‹ ÑобираетеÑÑŒ удалить вÑе примененные наÑтройки Ð´Ð»Ñ Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ оÑвещениÑ.
+Вы уверены, что хотите продолжить?
+ <usetemplate name="okcancelbuttons" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Ð’Ñ‹ ÑобираетеÑÑŒ импортировать непереноÑимые наÑтройки в Ñтот Ñуточный цикл. Ð’ Ñлучае дальнейшего Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñтих параметрах они также Ñтанут непереноÑимыми.
+
+Это изменение не подлежит отмене.
+
+Вы уверены, что хотите продолжить?
+ <usetemplate ignoretext="Ð’Ñ‹ уверены, что хотите Ñделать наÑтройки непереноÑимыми?" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Ð’Ñ‹ не можете редактировать наÑтройки непоÑредÑтвенно из библиотеки.
+Скопировать в Ñвой ÑобÑтвенный инвентарь и повторить попытку.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Мы ÑтолкнулиÑÑŒ Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¾Ð¹ Ñ Ñтими наÑтройками. Их невозможно Ñохранить или применить в данный момент.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Ðевозможно загрузить режим Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² [TRACK].
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Ðевозможно загрузить режим Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· [TRACK1] в [TRACK2].
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
index 874d5f8bc4..ed5312b723 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Тату на голове" name="Head Tattoo" tool_tip="Щелкните картинку, чтобы выбрать ее"/>
- <texture_picker label="Тату вверху" name="Upper Tattoo" tool_tip="Щелкните картинку, чтобы выбрать ее"/>
- <texture_picker label="Тату внизу" name="Lower Tattoo" tool_tip="Щелкните картинку, чтобы выбрать ее"/>
- <color_swatch label="Цвет/оттенок" name="Color/Tint" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Тату на голове" name="Head Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на верхних чаÑÑ‚ÑÑ… тела" name="Upper Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на нижних чаÑÑ‚ÑÑ… тела" name="Lower Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <color_swatch label="Цвет/оттенок" name="Color/Tint" tool_tip="Щелкнуть Ð´Ð»Ñ Ð¿Ð¾ÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ñ‹ цветов"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_universal.xml b/indra/newview/skins/default/xui/ru/panel_edit_universal.xml
new file mode 100644
index 0000000000..647d1aa9e7
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Тату на голове" name="Head Universal Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на верхних чаÑÑ‚ÑÑ… тела" name="Upper Universal Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на нижних чаÑÑ‚ÑÑ… тела" name="Lower Universal Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на юбке" name="Skirt Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату волоÑ" name="Hair Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату глаз" name="Eyes Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на левой руке" name="Left Arm Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату на левой ноге" name="Left Leg Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату Aux1" name="Aux1 Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату Aux2" name="Aux2 Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <texture_picker label="Тату Aux3" name="Aux3 Tattoo" tool_tip="Щелкнуть Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <color_swatch label="Цвет/оттенок" name="Color/Tint" tool_tip="Щелкнуть Ð´Ð»Ñ Ð¿Ð¾ÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ñ‹ цветов"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml b/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
index 79130a9c80..cede43f859 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Изменение тату
</string>
+ <string name="edit_universal_title">
+ Редактирование универÑальных
+ </string>
<string name="edit_physics_title">
Изменение физики
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Тату:
</string>
+ <string name="universal_desc_text">
+ УниверÑальные:
+ </string>
<string name="physics_desc_text">
Физика:
</string>
diff --git a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
deleted file mode 100644
index 0095d48af9..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Перетащите вещи Ñюда, чтобы подготовить их Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð½Ð° витрине вашего магазина"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 0fdc06fb32..0812eb7433 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -18,7 +18,7 @@
<string name="no_groups_msg" value="Ищете группу, чтобы приÑоединитьÑÑ Ðº ней? ВоÑпользуйтеÑÑŒ [secondlife:///app/search/groups поиÑком]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Двойной щелчок открывает карту, shift+перетÑгивание – обзор)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Двойной щелчок – телепортациÑ, shift+перетÑгивание – обзор)"/>
- <string name="GroupCountWithInfo" value="Ð’Ñ‹ входите в [COUNT] групп и можете приÑоединитьÑÑ ÐµÑ‰Ðµ к [REMAINING]. [secondlife:/// Хотите еще?]"/>
+ <string name="GroupCountWithInfo" value="Ð’Ñ‹ ÑоÑтоите в [COUNT] группах, и можете приÑоединитьÑÑ ÐµÑ‰Ðµ к [REMAINING]. [secondlife:/// РаÑширить Ñвои лимиты]"/>
<tab_container name="tabs">
<panel label="РЯДОМ" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@
<dnd_button name="minus_btn" tool_tip="Покинуть выбранную группу"/>
</panel>
<text name="groupcount">
- Ð’Ñ‹ входите в [COUNT] групп и можете приÑоединитьÑÑ ÐµÑ‰Ðµ к [REMAINING].
+ Ð’Ñ‹ ÑоÑтоите в [COUNT] группах, и можете приÑоединитьÑÑ ÐµÑ‰Ðµ к [REMAINING].
</text>
</panel>
<panel label="ÐЕДÐÐ’ÐИЕ" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
index dd0cf8e172..79d5cb7960 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
@@ -28,5 +28,5 @@
<check_box label="Выбор Ñетки при входе" name="show_grid_selection_check"/>
<check_box label="Показывать раÑширенное меню" name="show_advanced_menu_check"/>
<check_box label="Показать меню разработчика" name="show_develop_menu_check"/>
- <button label="Стандартные Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° Ñоздание" name="default_creation_permissions"/>
+ <button label="Стандартные Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° Ñоздание" name="default_creation_permissions" width="235"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
index c2fcac8840..03a714f266 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
@@ -5,15 +5,15 @@
<check_box initial_value="true" label="ВоÑпроизводить анимацию ввода текÑта при общении" name="play_typing_animation"/>
<check_box label="ОтправлÑть мне ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ почте, когда Ð¼ÐµÐ½Ñ Ð½ÐµÑ‚ в Ñети" name="send_im_to_email"/>
<check_box label="Только Ð´Ñ€ÑƒÐ·ÑŒÑ Ð¸ группы могут звонить мне и отправлÑть IM" name="voice_call_friends_only_check"/>
- <text name="font_size">
+ <text name="font_size" left="361">
Размер шрифта:
</text>
- <combo_box name="chat_font_size">
+ <combo_box name="chat_font_size" left="361">
<item label="Мелкий" name="Small" value="0"/>
<item label="Средний" name="Medium" value="1"/>
<item label="Крупный" name="Large" value="2"/>
</combo_box>
- <check_box label="Чат в пузырьках" name="bubble_text_chat"/>
+ <check_box label="Чат в пузырьках" name="bubble_text_chat" left_delta="19"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
index 4524fb4d43..f392a1f0b7 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
@@ -32,7 +32,7 @@
</text>
<check_box initial_value="true" label="Ð’Ñегда риÑовать друзей" name="AlwaysRenderFriends"/>
<button label="ИÑключениÑ..." name="RenderExceptionsButton"/>
- <button label="Сохранить наÑтройки как преÑет..." name="PrefSaveButton"/>
+ <button label="Сохранить наÑтройки как преÑет..." name="PrefSaveButton" width="210"/>
<button label="Загрузить преÑет..." name="PrefLoadButton"/>
min_val=&quot;0,125&quot;
<button label="Удалить преÑет..." name="PrefDeleteButton"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
index d4d0ef9e7c..137e047d97 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
@@ -14,7 +14,7 @@
<text name="Web:">
Браузер:
</text>
- <radio_group name="preferred_browser_behavior">
+ <radio_group name="preferred_browser_behavior" left_delta="30">
<radio_item label="ИÑпользуйте вÑтроенный браузер Ð´Ð»Ñ Ð²Ñех ÑÑылок" name="internal" tool_tip="Будет иÑпользоватьÑÑ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€, заданный в ÑиÑтеме по умолчанию. Ðе рекомендуетÑÑ, еÑли [APP_NAME] работает в полноÑкранном режиме." value="0"/>
<radio_item label="Ð”Ð»Ñ ÑÑылок Second Life Ñледует иÑпользовать только вÑтроенный браузер" name="external" tool_tip="ИÑпользуйте вÑтроенный браузер Ð´Ð»Ñ Ñправки, веб-ÑÑылок и Ñ‚.д. Ð”Ð»Ñ ÑÑылок LindenLab/Second Life Ñледует иÑпользовать только вÑтроенный браузер." value="1"/>
<radio_item label="Ð”Ð»Ñ Ð²Ñех ÑÑылок Ñледует иÑпользовать вÑтроенный браузер" name="external_all" tool_tip="Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñправки, ÑÑылок на веб-Ñтраницы и Ñ‚. д. будет иÑпользоватьÑÑ Ð²Ñтроенный браузер. Этот браузер открываетÑÑ ÐºÐ°Ðº новое окно в [APP_NAME]." value="2"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_environment.xml b/indra/newview/skins/default/xui/ru/panel_region_environment.xml
index 8057176cfb..fcf1548ae5 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Среда" name="panel_env_info">
- <text name="water_settings_title">
- ÐаÑтройки воды и неба/Ñуточного цикла определÑÑŽÑ‚, каким поÑетители увидÑÑ‚ ваш регион. Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="ИÑпользовать наÑтройки Second Life по умолчанию" name="use_sl_default_settings"/>
- <radio_item label="ИÑпользовать Ñледующие наÑтройки" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- ÐаÑтройка воды
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Выбор наÑтройки-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Ðебо/Ñуточный цикл
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="ЗафикÑированное небо" name="my_sky_settings"/>
- <radio_item label="Суточный цикл" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Выбор наÑтройки-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Выбор наÑтройки-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Применить" name="apply_btn"/>
- <button label="Отмена" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ ИÑпользовать наÑтройки по умолчанию
+ </string>
+ <string name="str_label_use_region">
+ ИÑпользовать наÑтройки региона
+ </string>
+ <string name="str_altitude_desription">
+ Ðебо [INDEX]([ALTITUDE]м)
+ </string>
+ <string name="str_no_parcel">
+ Ðе выбрано ни одного учаÑтка. ÐаÑтройки Ñреды отключены.
+ </string>
+ <string name="str_cross_region">
+ ÐаÑтройки окружающей Ñреды недоÑтупны в рамках Ñтого региона.
+ </string>
+ <string name="str_legacy">
+ ÐаÑтройки Ñреды недоÑтупны Ð´Ð»Ñ Ñтого региона.
+ </string>
+ <string name="str_disallowed">
+ УправлÑющий недвижимоÑтью не разрешает менÑть Ñреду вокруг учаÑтка в Ñтом регионе.
+ </string>
+ <string name="str_too_small">
+ Чтобы поддерживать наÑтройки окружающей Ñреды учаÑток должен быть не менее 128 кв. метров.
+ </string>
+ <string name="str_empty">
+ (пуÑто)
+ </string>
+ <string name="str_region_env">
+ (Ñреда региона)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="ИÑпользовать инвентарь" name="btn_select_inventory"/>
+ <button label="ÐаÑтроить" name="btn_edit"/>
+ <check_box label="Владельцы учаÑтков могут менÑть окружающую Ñреду" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Ðебо [INDEX]
+ [ALTITUDE]м
+ </text>
+ <line_editor name="edt_invname_alt1">
+ ÐеизвеÑтно
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Перетащить наÑтройки из Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð° Ñто целевое поле, чтобы выбрать его в качеÑтве неба на наÑтоÑщий момент."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Ðебо [INDEX]
+ [ALTITUDE]м
+ </text>
+ <line_editor name="edt_invname_alt2">
+ ÐеизвеÑтно
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Перетащить наÑтройки из Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð° Ñто целевое поле, чтобы выбрать его в качеÑтве неба на наÑтоÑщий момент."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Ðебо [INDEX]
+ [ALTITUDE]м
+ </text>
+ <line_editor name="edt_invname_alt3">
+ ÐеизвеÑтно
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Перетащить наÑтройки из Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð° Ñто целевое поле, чтобы выбрать его в качеÑтве неба на наÑтоÑщий момент."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ ЗемлÑ
+ </text>
+ <line_editor name="edt_invname_ground">
+ ÐеизвеÑтно
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Перетащить наÑтройки из Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð° Ñто целевое поле Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° его в качеÑтве неба на уровне земли."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Вода
+ </text>
+ <line_editor name="edt_invname_water">
+ ÐеизвеÑтно
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Перетащить наÑтройки из Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð° Ñто целевое поле Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° его в качеÑтве воды на наÑтоÑщий момент."/>
+ </panel>
+ <button label="СброÑ" name="btn_rst_altitudes" tool_tip="СброÑить наÑтройки по умолчанию"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/ru/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..9c4c502694
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ÐтмоÑфера и оÑвещение" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/ru/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..46b4b10125
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Облака" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/ru/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..8886ceb539
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ПлотноÑть" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="ЭкÑпоненциальный член РÑлеÑ:" name="rayleigh_exponential"/>
+ <slider label="ЭкÑÐ¿Ð¾Ð½ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐºÐ°Ð»Ð° РÑлеÑ:" name="rayleigh_exponential_scale"/>
+ <slider label="Линейный член РÑлеÑ:" name="rayleigh_linear"/>
+ <slider label="ПоÑтоÑнный член РÑлеÑ:" name="rayleigh_constant"/>
+ <slider label="МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота РÑлеÑ:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="ЭкÑпоненциальный член Мие:" name="mie_exponential"/>
+ <slider label="ЭкÑÐ¿Ð¾Ð½ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐºÐ°Ð»Ð° Мие:" name="mie_exponential_scale"/>
+ <slider label="Линейный член Мие:" name="mie_linear"/>
+ <slider label="ПоÑтоÑнный член Мие:" name="mie_constant"/>
+ <slider label="Ðнизо-фактор Мие:" name="mie_aniso_factor"/>
+ <slider label="МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота Мие:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="ЭкÑпоненциальный член абÑорбции:" name="absorption_exponential"/>
+ <slider label="ЭкÑÐ¿Ð¾Ð½ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐºÐ°Ð»Ð° абÑорбции:" name="absorption_exponential_scale"/>
+ <slider label="Линейный член абÑорбции:" name="absorption_linear"/>
+ <slider label="ПоÑтоÑнный член абÑорбции:" name="absorption_constant"/>
+ <slider label="МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота абÑорбции:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/ru/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..a494bbbe0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Солнце и луна" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="Показать метку" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="Показать метку" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_settings_water.xml b/indra/newview/skins/default/xui/ru/panel_settings_water.xml
new file mode 100644
index 0000000000..de8b15ac19
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Вода" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Ð£Ð³Ð»Ð¾Ð²Ð°Ñ Ð·Ð°Ð²Ð¸ÑимоÑть:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_tools_texture.xml b/indra/newview/skins/default/xui/ru/panel_tools_texture.xml
index 707578cd07..5cd83c712f 100644
--- a/indra/newview/skins/default/xui/ru/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/ru/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="ТекÑтура" name="Texture">
- <panel.string name="string repeats per meter">
- Повторений на метр
- </panel.string>
- <panel.string name="string repeats per face">
- Повторений на грань
- </panel.string>
<text name="color label">
Цвет
</text>
@@ -114,4 +108,5 @@
<spinner label="Смещение по горизонтали" name="shinyOffsetU"/>
<spinner label="Смещение по вертикали" name="shinyOffsetV"/>
<check_box initial_value="false" label="СоглаÑование" name="checkbox planar align" tool_tip="СоглаÑование текÑтур на вÑех выбранных гранÑÑ… по поÑледней выбранной грани. Должно быть выбрано наложение по плоÑкоÑÑ‚Ñм."/>
+ <button label="ВыровнÑть" label_selected="ВыровнÑть текущие Ñлои текÑтуры" name="button align textures" tool_tip="ВыровнÑть текущие Ñлои текÑтуры"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/role_actions.xml b/indra/newview/skins/default/xui/ru/role_actions.xml
index 1d526b90e4..314f6b9cb5 100644
--- a/indra/newview/skins/default/xui/ru/role_actions.xml
+++ b/indra/newview/skins/default/xui/ru/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Изменение наÑтроек музыки и медиа" longdescription="Измените наÑтройки потоковой музыки и фильмов в окне «О земле» на вкладке «Медиа»." name="land change media" value="20"/>
<action description="Включение-отключение Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð»Ð°Ð½Ð´ÑˆÐ°Ñ„Ñ‚Ð°" longdescription="Включение-отключение Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð»Ð°Ð½Ð´ÑˆÐ°Ñ„Ñ‚Ð°. *ПРЕДУПРЕЖДЕÐИЕ* Выбрав параметры «О земле» &gt; вкладка «Параметры» &gt; «Изменить ландшафт», любой пользователь может изменить форму земли, а также размещать или перемещать раÑÑ‚ÐµÐ½Ð¸Ñ Linden. Прежде чем назначить Ñту ÑпоÑобноÑть, убедитеÑÑŒ в целеÑообразноÑти Ñтого. Изменить ландшафт можно в окне «О земле» на вкладке «Параметры»." name="land edit" value="21"/>
<action description="Включение-отключение различных наÑтроек «О земле &gt; Параметры»" longdescription="Ð’ окне «О земле» на вкладке «Параметры» можно включить-отключить параметр «БезопаÑно (нет повреждений)», «Полет» и разрешить другим жителÑм изменÑть ландшафт, ÑтроительÑтво, Ñоздавать закладки и запуÑкать Ñкрипты Ð´Ð»Ñ Ð·ÐµÐ¼Ð»Ð¸ группы." name="land options" value="22"/>
+ <action description="Изменить уÑтановки окружающей Ñреды и Ñуточного цикла." longdescription="Изменить уÑтановки окружающей Ñреды и Ñуточного цикла от «О земле» &gt; Вкладка окружающей Ñреды." name="land change environment" value="46"/>
</action_set>
<action_set description="К Ñтим ÑпоÑобноÑÑ‚Ñм отноÑитÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ учаÑтникам обходить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° учаÑтках группы." name="Parcel Powers">
<action description="Ð’Ñегда разрешено изменение ландшафта" longdescription="УчаÑтники роли Ñ Ñтой ÑпоÑобноÑтью могут изменÑть ландшафт учаÑтка группы, даже еÑли Ñто отключено в окне «О земле» на вкладке «Параметры»." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 9c01de2f1b..e9592a0476 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -639,6 +639,15 @@ support@secondlife.com.
<string name="BUTTON_HELP">
Показать Ñправку
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Элементы Ñтого типа не могут быть занеÑены в
+карточку Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ² в Ñтом регионе.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Только Ñлементы Ñ Ð±ÐµÐ·ÑƒÑловным разрешением
+‘Ñледующего владельца’ можно внеÑти
+в карточки Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ².
+ </string>
<string name="Searching">
ПоиÑк...
</string>
@@ -715,6 +724,18 @@ support@secondlife.com.
Ошибка при запроÑе на передачу. Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰Ð¸ в
решении Ñтой проблемы пройдите по ÑÑылке http://secondlife.com/support.
</string>
+ <string name="SettingValidationError">
+ Ðе удалоÑÑŒ выполнить проверку Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð° наÑтроек [NAME]
+ </string>
+ <string name="SettingImportFileError">
+ Ðе удалоÑÑŒ открыть файл [FILE]
+ </string>
+ <string name="SettingParseFileError">
+ Ðе удалоÑÑŒ открыть файл [FILE]
+ </string>
+ <string name="SettingTranslateError">
+ Ðе удалоÑÑŒ применить уÑтаревший Ñффект windlight \[NAME]
+ </string>
<string name="texture">
текÑтуру
</string>
@@ -790,6 +811,9 @@ support@secondlife.com.
<string name="symbolic folder link">
ÑÑылку на папку
</string>
+ <string name="settings blob">
+ наÑтройки
+ </string>
<string name="mesh">
Ñетка
</string>
@@ -1120,6 +1144,9 @@ support@secondlife.com.
<string name="ForceSitAvatar">
ЗаÑтавьте аватар ÑеÑть
</string>
+ <string name="ChangeEnvSettings">
+ Изменить Ñвои наÑтройки окружающей Ñреды
+ </string>
<string name="NotConnected">
Ðет подключениÑ
</string>
@@ -1271,6 +1298,9 @@ support@secondlife.com.
<string name="tattoo">
Тату
</string>
+ <string name="universal">
+ УниверÑальные
+ </string>
<string name="physics">
ФизичеÑкие данные
</string>
@@ -1313,6 +1343,9 @@ support@secondlife.com.
<string name="tattoo_not_worn">
Тату не надето
</string>
+ <string name="universal_not_worn">
+ УниверÑальный нарÑд не надет
+ </string>
<string name="physics_not_worn">
Физика не учитываетÑÑ
</string>
@@ -1364,6 +1397,9 @@ support@secondlife.com.
<string name="create_new_tattoo">
Создать тату
</string>
+ <string name="create_new_universal">
+ Создать новые универÑальные
+ </string>
<string name="create_new_physics">
Создать физику
</string>
@@ -1607,11 +1643,14 @@ support@secondlife.com.
<string name="MarketplaceUpdating">
обновление...
</string>
+ <string name="UploadFeeInfo">
+ Тариф завиÑит от типа вашей подпиÑки. Тарифы Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ² раÑширенных пакетов меньше. [https://secondlife.com/my/account/membership.php? Узнать больше]
+ </string>
<string name="Open landmarks">
- Открыть закладки
+ Открыть Ñохраненные локации
</string>
<string name="Unconstrained">
- Без ограничениÑ
+ Без ограничений
</string>
<string name="no_transfer" value="(не передаетÑÑ)"/>
<string name="no_modify" value="(не изменÑетÑÑ)"/>
@@ -2511,6 +2550,27 @@ support@secondlife.com.
<string name="RegionSettings">
Региональные наÑтройки
</string>
+ <string name="NoEnvironmentSettings">
+ Этот регион не поддерживает наÑтройки окружающей Ñреды.
+ </string>
+ <string name="EnvironmentSun">
+ Солнце
+ </string>
+ <string name="EnvironmentMoon">
+ Луна
+ </string>
+ <string name="EnvironmentBloom">
+ Ореол
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Шум облака
+ </string>
+ <string name="EnvironmentNormalMap">
+ Карта Ðормалей
+ </string>
+ <string name="EnvironmentTransparent">
+ Прозрачный
+ </string>
<string name="ClassifiedClicksTxt">
Щелчки: телепорт [TELEPORT], карта [MAP], профиль [PROFILE]
</string>
@@ -4724,6 +4784,9 @@ support@secondlife.com.
<string name="New Tattoo">
Ðовое тату
</string>
+ <string name="New Universal">
+ Ðовые универÑальные
+ </string>
<string name="New Physics">
ÐÐ¾Ð²Ð°Ñ Ñ„Ð¸Ð·Ð¸ÐºÐ°
</string>
@@ -4850,6 +4913,15 @@ support@secondlife.com.
<string name="Female - Wow">
Женщина – ух ты!
</string>
+ <string name="New Daycycle">
+ Ðовый Ñуточный цикл
+ </string>
+ <string name="New Water">
+ ÐÐ¾Ð²Ð°Ñ Ð²Ð¾Ð´Ð°
+ </string>
+ <string name="New Sky">
+ Ðовое небо
+ </string>
<string name="/bow">
/поклонитьÑÑ
</string>
@@ -5022,6 +5094,15 @@ support@secondlife.com.
<string name="Chat">
Чат
</string>
+ <string name="BaseMembership">
+ Базовый
+ </string>
+ <string name="PremiumMembership">
+ Премиум
+ </string>
+ <string name="Premium PlusMembership">
+ Премиум ПлюÑ
+ </string>
<string name="DeleteItems">
Удалить выбранные объекты?
</string>
@@ -5390,6 +5471,12 @@ support@secondlife.com.
<string name="BeaconMedia">
ПроÑмотр медийных меток (белые)
</string>
+ <string name="BeaconSun">
+ ПроÑмотр метки Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñолнца (оранжевый)
+ </string>
+ <string name="BeaconMoon">
+ ПроÑмотр метки Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð»ÑƒÐ½Ñ‹ (багровый)
+ </string>
<string name="ParticleHiding">
ЧаÑтицы Ñкрыты
</string>
@@ -5417,6 +5504,12 @@ support@secondlife.com.
<string name="Command_Destinations_Label">
Пункты
</string>
+ <string name="Command_Environments_Label">
+ ÐœÐ¾Ñ Ð¾ÐºÑ€ÑƒÐ¶Ð°ÑŽÑ‰Ð°Ñ Ñреда
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5510,6 +5603,12 @@ support@secondlife.com.
<string name="Command_Destinations_Tooltip">
ИнтереÑные меÑта
</string>
+ <string name="Command_Environments_Tooltip">
+ ÐœÐ¾Ñ Ð¾ÐºÑ€ÑƒÐ¶Ð°ÑŽÑ‰Ð°Ñ Ñреда
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Опубликовать в Facebook
+ </string>
<string name="Command_Flickr_Tooltip">
Загрузить на Flickr
</string>
@@ -5705,6 +5804,12 @@ support@secondlife.com.
<string name="ExperiencePermission12">
автоматичеÑки принимать Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¸ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ
</string>
+ <string name="ExperiencePermission16">
+ поÑадить аватара
+ </string>
+ <string name="ExperiencePermission17">
+ изменить Ñвои наÑтройки окружающей Ñреды
+ </string>
<string name="ExperiencePermissionShortUnknown">
выполнил неизвеÑтную операцию: [Permission]
</string>
@@ -5729,6 +5834,12 @@ support@secondlife.com.
<string name="ExperiencePermissionShort12">
Разрешение
</string>
+ <string name="ExperiencePermissionShort16">
+ СеÑть
+ </string>
+ <string name="ExperiencePermissionShort17">
+ ÐžÐºÑ€ÑƒÐ¶Ð°ÑŽÑ‰Ð°Ñ Ñреда
+ </string>
<string name="logging_calls_disabled_log_empty">
Разговоры не запиÑываютÑÑ. Чтобы начать запиÑÑŒ разговора, в меню «ÐаÑтройки &gt; Чат» выберите «СохранÑть: только журнал» или «СохранÑть: журнал и запиÑи».
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_about_land.xml b/indra/newview/skins/default/xui/tr/floater_about_land.xml
index 48b16e2fde..f9dbda0378 100644
--- a/indra/newview/skins/default/xui/tr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about_land.xml
@@ -360,10 +360,10 @@ Sadece büyük parseller aramada görünür.
Anlık Görüntü:
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Bir resim seçmek için tıklayın"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Diğer parsellerdeki avatarlar bu parseldeki avatarları görebilir ve onlarla sohbet edebilir
</text>
- <check_box label="Avatarları Gör" name="SeeAvatarsCheck" tool_tip="Diğer parsellerdeki avatarların bu parseldeki avatarları görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
+ <check_box label="Avatarları Gör" name="SeeAvatarsCheck" top="170" tool_tip="Diğer parsellerdeki avatarların bu parseldeki avatarları görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
<text name="landing_point">
İniş Noktası: [LANDING]
</text>
@@ -474,5 +474,6 @@ Sadece büyük parseller aramada görünür.
</panel>
</panel>
<panel label="DENEYİMLER" name="land_experiences_panel"/>
+ <panel label="ORTAM" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_adjust_environment.xml b/indra/newview/skins/default/xui/tr/floater_adjust_environment.xml
new file mode 100644
index 0000000000..763845c54d
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="Kişisel Aydınlatma">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="Sıfırla" name="btn_reset" tool_tip="Kapat ve Ortak Ortama sıfırla"/>
+ <text name="cloud_map_label">
+ Bulut Görüntüsü:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ Güneş:
+ </text>
+ <check_box label="İşareti Göster" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="İşareti Göster" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_beacons.xml b/indra/newview/skins/default/xui/tr/floater_beacons.xml
index 08ebf36be5..e5b598ee61 100644
--- a/indra/newview/skins/default/xui/tr/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/tr/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="Ses kaynakları" name="sounds"/>
<check_box label="Parçacık kaynakları" name="particles"/>
<check_box label="Ortam kaynakları" name="moapbeacon"/>
+ <check_box label="Güneş" name="sun"/>
+ <check_box label="Ay" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
index a7708b5882..4eee1b81a2 100644
--- a/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
@@ -21,6 +21,7 @@
<icon name="icon_script" tool_tip="Komut Dosyaları"/>
<icon name="icon_sound" tool_tip="Sesler"/>
<icon name="icon_texture" tool_tip="Dokular"/>
+ <icon name="icon_setting" tool_tip="Ortam ayarları"/>
<button label="√ Tümü" name="check_all"/>
<button label="Temizle" label_selected="Hiçbiri" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
index d90985dcff..33c4b2287f 100644
--- a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="Şimdi Satın Al" name="buy_btn"/>
<button label="İptal" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
Satın Alınamıyor
- </text>
- <button label="Web&apos;e devam et" name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml
deleted file mode 100644
index 7634bea642..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="ORTAM ÖN AYARINI SİL">
- <string name="title_water">
- Su Ön Ayarını Sil
- </string>
- <string name="title_sky">
- Gökyüzü Ön Ayarını Sil
- </string>
- <string name="title_day_cycle">
- Gün Döngüsünü Sil
- </string>
- <string name="label_water">
- Ön Ayar:
- </string>
- <string name="label_sky">
- Ön Ayar:
- </string>
- <string name="label_day_cycle">
- Gün döngüsü:
- </string>
- <string name="msg_confirm_deletion">
- Seçili ön ayarı silmek istediğinizden emin misiniz?
- </string>
- <string name="msg_sky_is_referenced">
- Bazı gün döngüleri tarafından referans alınan bir ön ayar kaldırılamaz.
- </string>
- <string name="combo_label">
- -Bir ön ayar seçin-
- </string>
- <text name="label">
- Ön Ayar:
- </text>
- <button label="Sil" name="delete"/>
- <button label="İptal Et" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/tr/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..7ebbafa9bc
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="Gün Döngüsünü Düzenle">
+ <string name="title_new">
+ Yeni bir Gün Döngüsü Oluştur
+ </string>
+ <string name="title_edit">
+ Gün Döngüsünü Düzenle
+ </string>
+ <string name="hint_new">
+ Gün döngünüze ad verin, bunu oluşturmak için denetimleri ayarlayın ve &quot;Kaydet&quot; düğmesine tıklayın.
+ </string>
+ <string name="hint_edit">
+ Gün döngünüzü düzenlemek için, alttaki denetimleri ayarlayın ve &quot;Kaydet&quot; düğmesine tıklayın.
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ Gökyüzü [ALT]
+ </string>
+ <string name="sky_label">
+ Gökyüzü
+ </string>
+ <string name="water_label">
+ Su
+ </string>
+ <string name="commit_parcel">
+ Parsele Uygula
+ </string>
+ <string name="commit_region">
+ Bölgeye Uygula
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ Gün Döngüsü Adı:
+ </text>
+ <button label="İçeri Aktar" name="btn_import" tool_tip="Eski ayarları diskten içeri aktarın."/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="Gökyüzü 4" name="sky4_track"/>
+ <button label="Gökyüzü 3" name="sky3_track"/>
+ <button label="Gökyüzü 2" name="sky2_track"/>
+ <button label="Zemin Seviyesi" name="sky1_track"/>
+ <button label="Su" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="%0 [DSC]"/>
+ <text name="p1" value="%25 [DSC]"/>
+ <text name="p2" value="%50 [DSC]"/>
+ <text name="p3" value="%75 [DSC]"/>
+ <text name="p4" value="%100 [DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="%[PRCNT] [DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="Buradan Rota Kopyala:" name="copy_track"/>
+ <button label="Buradan Rota Yükle:" name="load_track"/>
+ <button label="Rotayı Temizle" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="Geri çekil"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="İleri çık"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="[FRAME] Ekle" name="add_frame"/>
+ <button label="[FRAME] Yükle" name="btn_load_frame"/>
+ <button label="[FRAME] Sil" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ Ayarları düzenlemek için yukarıdaki zaman çizelgesinden bir anahtar çerçeve seçin.
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="Su" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="Atmosfer ve Aydınlatma" name="atmosphere_panel"/>
+ <panel label="Bulutlar" name="clouds_panel"/>
+ <panel label="Güneş ve Ay" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="Kaydet" name="save_btn"/>
+ <button label="İptal Et" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/tr/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..8a8757c86c
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="Sabit Ortam">
+ <string name="edit_sky">
+ Gökyüzünü Düzenle:
+ </string>
+ <string name="edit_water">
+ Suyu Düzenle:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="Yükle" name="btn_load" tool_tip="Envanterden bir ayar yükle"/>
+ <button label="İçeri Aktar" name="btn_import" tool_tip="Eski ayarları diskten içeri aktarın."/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="Kaydet" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="İptal Et" name="btn_cancel" tool_tip="Son kaydedilen sürüme dön"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
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 6c04b64275..accb1ed71c 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
@@ -12,6 +12,7 @@
<check_box label="Sesler" name="check_sound"/>
<check_box label="Dokular" name="check_texture"/>
<check_box label="Anlık Görüntüler" name="check_snapshot"/>
+ <check_box label="Ayarlar" name="check_settings"/>
<button label="Tümü" label_selected="Tümü" name="All"/>
<button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
<check_box label="Klasörleri her zaman göster" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
deleted file mode 100644
index e5643f3bf6..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="SATICI GİDEN KUTUSU">
- <string name="OutboxFolderCount1">
- 1 klasör
- </string>
- <string name="OutboxFolderCountN">
- [NUM] klasör
- </string>
- <string name="OutboxImporting">
- Klasörler gönderiliyor...
- </string>
- <string name="OutboxInitializing">
- Başlatılıyor...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Yükleniyor...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Klasör oluşturmak için öğeleri buraya sürükleyin
- </text>
- </panel>
- <button label="Pazaryerine Gönder" name="outbox_import_btn" tool_tip="Pazaryeri Vitrinime Gönder"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_my_environments.xml b/indra/newview/skins/default/xui/tr/floater_my_environments.xml
new file mode 100644
index 0000000000..b91f48c500
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="Yerler" name="my_environments" title="ORTAMLARIM">
+ <layout_stack>
+ <layout_panel label="Filtreler" name="filter_panel">
+ <check_box label="Günler" name="chk_days"/>
+ <check_box label="Gökler" name="chk_skies"/>
+ <check_box label="Su" name="chk_water"/>
+ <filter_editor label="Ortamları Filtrele" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="Ortamlar" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="Tüm Klasörleri Göster" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="Diğer seçenekler"/>
+ <menu_button name="btn_newsettings" tool_tip="Yeni ayar oluÅŸtur"/>
+ <button name="btn_del" tool_tip="Seçilen öğeyi kaldır"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_perms_default.xml b/indra/newview/skins/default/xui/tr/floater_perms_default.xml
index 9691b678f2..9263d4e1c6 100644
--- a/indra/newview/skins/default/xui/tr/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/tr/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="Giysi ya da Vücut Parçaları oluşturulduğunda varsayılan izinleri ayarla">
Giyilebilir öğeler
</text>
+ <text name="label_13" tool_tip="Ortam ayarları oluşturulduğunda varsayılan izinleri ayarla">
+ Ayarlar
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="Tamam" label_selected="Tamam" name="ok"/>
<button label="İptal" label_selected="İptal" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_pick_track.xml b/indra/newview/skins/default/xui/tr/floater_pick_track.xml
new file mode 100644
index 0000000000..83cfa8b652
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="SEÇİM: ROTA">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ Kaynak gökyüzünü seç
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="Gökyüzü 4 [ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="Gökyüzü 3 [ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="Gökyüzü 2 [ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="Zemin" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="Tamam" label_selected="Tamam" name="btn_select"/>
+ <button label="İptal Et" label_selected="İptal Et" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
index 513a2e319a..5aee6ae091 100644
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/tr/floater_picks.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Seçmeler"/>
+<floater name="floater_picks" title="Seçimler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml
index 01ada1354c..c5ca997336 100644
--- a/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="Saydam Su" name="TransparentWater"/>
<check_box initial_value="true" label="Tümsek eşleme ve parlaklık" name="BumpShiny"/>
<check_box initial_value="true" label="Yerel Işıklar" name="LocalLights"/>
- <check_box initial_value="true" label="Temel gölgeleyiciler" name="BasicShaders" tool_tip="Bu seçeneğin devre dışı bırakılması bazı grafik kartlarının sürücülerinin kilitlenmesini önleyebilir"/>
<slider label="Yüzey Ayrıntısı:" name="TerrainDetail"/>
<text name="TerrainDetailText">
Düşük
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 79e184130a..8302c62070 100644
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
@@ -10,7 +10,7 @@
Açıklama:
</text>
<text name="dimensions">
- [WIDTH]px x [HEIGHT]px
+ [WIDTH] pks x [HEIGHT] pks
</text>
<text name="aspect_ratio">
En boy oranını önizle
diff --git a/indra/newview/skins/default/xui/tr/floater_settings_picker.xml b/indra/newview/skins/default/xui/tr/floater_settings_picker.xml
new file mode 100644
index 0000000000..0ef3aad5ee
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="SEÇİM: AYARLAR">
+ <floater.string name="pick title">
+ Seçim:
+ </floater.string>
+ <floater.string name="pick_track">
+ ROTA SEÇ
+ </floater.string>
+ <floater.string name="pick_settings">
+ AYARLARI SEÇ
+ </floater.string>
+ <floater.string name="track_water">
+ Su
+ </floater.string>
+ <floater.string name="track_ground">
+ Zemin
+ </floater.string>
+ <floater.string name="track_sky">
+ Gökyüzü [NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="Dokuları Filtrele" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="Tamam" label_selected="Tamam" name="btn_select"/>
+ <button label="İptal Et" label_selected="İptal Et" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
index 42483c09e1..0389cdcbe5 100644
--- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
@@ -9,17 +9,13 @@
<text name="Multiple">
Birden çok doku
</text>
- <radio_group name="mode_selection">
- <radio_item label="Envanter" name="inventory" value="0"/>
- <radio_item label="Yerel" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- Büyüklük: [DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="Envanter" name="inventory" value="0"/>
+ <combo_box.item label="Yerel" name="local" value="1"/>
+ </combo_box>
<button label="Varsayılan" label_selected="Varsayılan" name="Default"/>
<button label="BoÅŸ" label_selected="BoÅŸ" name="Blank"/>
<button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
- <check_box initial_value="true" label="Åžimdi uygula" name="apply_immediate_check"/>
<text name="preview_disabled" value="Önizleme Devre Dışı"/>
<filter_editor label="Dokuları Filtrele" name="inventory search editor"/>
<check_box initial_value="false" label="Klasörleri göster" name="show_folders_check"/>
@@ -30,6 +26,22 @@
<column label="Ad" name="unit_name"/>
<column label="Kimlik" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="Kurutma dokusunu seçin">
+ <combo_box.item label="Yok" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="Temel Ağ Bölgesini Gizle" name="hide_base_mesh_region"/>
<button label="Tamam" label_selected="Tamam" name="Select"/>
<button label="İptal" label_selected="İptal" name="Cancel"/>
+ <check_box initial_value="true" label="Åžimdi uygula" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
index d57c43f6c1..82c9b286bb 100644
--- a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="Dokun" name="touch_attach" />
+ <menu_item_call label="Düzenle" name="edit_item" />
<menu_item_call label="Ayır" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml
index 1e8dfc7d68..ce85c437cb 100644
--- a/indra/newview/skins/default/xui/tr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="EtkinleÅŸtir" name="Marketplace Activate"/>
<menu_item_call label="Devre Dışı Bırak" name="Marketplace Deactivate"/>
<menu_item_call label="PaylaÅŸ" name="Share"/>
- <menu_item_call label="Satın Al" name="Task Buy"/>
<menu_item_call label="Aç" name="Task Open"/>
<menu_item_call label="Oyna" name="Task Play"/>
<menu_item_call label="Özellikler" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="Yeni Külot" name="New Underpants"/>
<menu_item_call label="Yeni Alfa Maskesi" name="New Alpha Mask"/>
<menu_item_call label="Yeni Dövme" name="New Tattoo"/>
+ <menu_item_call label="Yeni Evrensel" name="New Universal"/>
<menu_item_call label="Yeni Fizik" name="New Physics"/>
</menu>
<menu label="Yeni Vücut Bölümleri" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="Yeni Saç" name="New Hair"/>
<menu_item_call label="Yeni Gözler" name="New Eyes"/>
</menu>
+ <menu label="Yeni Ayarlar" name="New Settings">
+ <menu_item_call label="Yeni Gökyüzü" name="New Sky"/>
+ <menu_item_call label="Yeni Su" name="New Water"/>
+ <menu_item_call label="Yeni Gün Döngüsü" name="New Day Cycle"/>
+ </menu>
<menu label="Şunun için varsayılan olarak kullan" name="upload_def">
<menu_item_call label="Karşıya yüklenen görüntüler" name="Image uploads"/>
<menu_item_call label="Karşıya yüklenen sesler" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="Giy" name="Wearable And Object Wear"/>
<menu label="Åžuna Ekle:" name="Attach To"/>
<menu label="BÜG&apos;e Ekle" name="Attach To HUD"/>
+ <menu_item_call label="Dokun" name="Attachment Touch" />
<menu_item_call label="Düzenle" name="Wearable Edit"/>
<menu_item_call label="Ekle" name="Wearable Add"/>
<menu_item_call label="Çıkar" name="Take Off"/>
+ <menu_item_call label="Sadece Kendime Uygula" name="Settings Apply Local"/>
+ <menu_item_call label="Parsele Uygula" name="Settings Apply Parcel"/>
<menu_item_call label="Pazaryeri İlanlarına Kopyala" name="Marketplace Copy"/>
<menu_item_call label="Pazaryeri İlanlarına Taşı" name="Marketplace Move"/>
<menu_item_call label="--seçenek yok--" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory_add.xml b/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
index db2a9a2c8c..118081e3a3 100644
--- a/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="Ses (L$[COST])..." name="Upload Sound"/>
<menu_item_call label="Animasyon (L$[COST])..." name="Upload Animation"/>
<menu_item_call label="Model..." name="Upload Model"/>
- <menu_item_call label="Model Sihirbazı..." name="Upload Model Wizard"/>
<menu_item_call label="Toplu (dosya başına L$[COST])..." name="Bulk Upload"/>
- <menu_item_call label="Varsayılan Karşıya Yükleme İzinlerini Ayarla" name="perm prefs"/>
</menu>
<menu_item_call label="Yeni Klasör" name="New Folder"/>
<menu_item_call label="Yeni Komut Dosyası" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="Yeni Külot" name="New Underpants"/>
<menu_item_call label="Yeni Alfa" name="New Alpha"/>
<menu_item_call label="Yeni Dövme" name="New Tattoo"/>
+ <menu_item_call label="Yeni Evrensel" name="New Universal"/>
<menu_item_call label="Yeni Fizik" name="New Physics"/>
</menu>
<menu label="Yeni Vücut Bölümleri" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="Yeni Saç" name="New Hair"/>
<menu_item_call label="Yeni Gözler" name="New Eyes"/>
</menu>
+ <menu label="Yeni Ayarlar" name="New Settings">
+ <menu_item_call label="Yeni Gökyüzü" name="New Sky"/>
+ <menu_item_call label="Yeni Su" name="New Water"/>
+ <menu_item_call label="Yeni Gün Döngüsü" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
index 1b73032a5d..7590ee28de 100644
--- a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="Yeni Alfa" name="New Alpha"/>
<menu_item_call label="Yeni Fizik" name="New Physics"/>
<menu_item_call label="Yeni Dövme" name="New Tattoo"/>
+ <menu_item_call label="Yeni Evrensel" name="New Universal"/>
</menu>
<menu label="Yeni Vücut Bölümleri" name="New Body Parts">
<menu_item_call label="Yeni Åžekil" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_save_settings.xml b/indra/newview/skins/default/xui/tr/menu_save_settings.xml
new file mode 100644
index 0000000000..dad150a54b
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="Kaydet" name="save_settings"/>
+ <menu_item_check label="Farklı Kaydet" name="save_as_new_settings"/>
+ <menu_item_check label="Yürüt" name="commit_changes"/>
+ <menu_item_check label="Sadece Kendime Uygula" name="apply_local"/>
+ <menu_item_check label="Parsele Uygula" name="apply_parcel"/>
+ <menu_item_check label="Bölgeye Uygula" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_settings_add.xml b/indra/newview/skins/default/xui/tr/menu_settings_add.xml
new file mode 100644
index 0000000000..0afd8a7893
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="Yeni Gökyüzü" name="New Sky"/>
+ <menu_item_call label="Yeni Su" name="New Water"/>
+ <menu_item_call label="Yeni Gün Döngüsü" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_settings_gear.xml b/indra/newview/skins/default/xui/tr/menu_settings_gear.xml
new file mode 100644
index 0000000000..f0d04a9e68
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="Düzenle" name="edit_settings"/>
+ <menu_item_call label="Sadece Kendime Uygula" name="Settings Apply Local"/>
+ <menu_item_call label="Parsele Uygula" name="Settings Apply Parcel"/>
+ <menu_item_call label="Bölgeye Uygula" name="Settings Apply Region"/>
+ <menu_item_call label="Kopyala" name="copy_settings"/>
+ <menu_item_call label="Yapıştır" name="paste_settings"/>
+ <menu_item_call label="UUID&apos;yi Kopyala" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index b83847a013..1c977ba5ce 100644
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -77,30 +77,15 @@
<menu_item_check label="Parsel Özellikleri" name="Parcel Properties"/>
<menu_item_check label="Gelişmiş Menü" name="Show Advanced Menu"/>
</menu>
- <menu label="Güneş" name="Sun">
+ <menu label="Ortam" name="Environment">
<menu_item_check label="Gün doğumu" name="Sunrise"/>
<menu_item_check label="Öğle" name="Noon"/>
<menu_item_check label="Gün batımı" name="Sunset"/>
<menu_item_check label="Gece yarısı" name="Midnight"/>
- <menu_item_check label="Bölge Ayarlarını Kullan" name="Use Region Settings"/>
- </menu>
- <menu label="Ortam Düzenleyici" name="Environment Editor">
- <menu_item_call label="Ortam Ayarları..." name="Environment Settings"/>
- <menu label="Su Ön Ayarları" name="Water Presets">
- <menu_item_call label="Yeni ön ayar..." name="new_water_preset"/>
- <menu_item_call label="Ön ayarı düzenle..." name="edit_water_preset"/>
- <menu_item_call label="Ön ayarı sil..." name="delete_water_preset"/>
- </menu>
- <menu label="Gökyüzü Ön Ayarları" name="Sky Presets">
- <menu_item_call label="Yeni ön ayar..." name="new_sky_preset"/>
- <menu_item_call label="Ön ayarı düzenle..." name="edit_sky_preset"/>
- <menu_item_call label="Ön ayarı sil..." name="delete_sky_preset"/>
- </menu>
- <menu label="Gün Ön Ayarları" name="Day Presets">
- <menu_item_call label="Yeni ön ayar..." name="new_day_preset"/>
- <menu_item_call label="Ön ayarı düzenle..." name="edit_day_preset"/>
- <menu_item_call label="Ön ayarı sil..." name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="Ortak Ortam Kullan" name="Use Shared Environment"/>
+ <menu_item_call label="Ortamlarım..." name="my_environs"/>
+ <menu_item_call label="Kişisel Aydınlatma..." name="adjustment_tool"/>
+ <menu_item_check label="Bulutları Duraklat" name="pause_clouds"/>
</menu>
</menu>
<menu label="İnşa Et" name="BuildTools">
@@ -344,6 +329,9 @@
<menu_item_check label="Otomatik Alfa Maskeleri (ertelenmemiÅŸ)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Animasyon Dokuları" name="Animation Textures"/>
<menu_item_check label="Dokuları Devre Dışı Bırak" name="Disable Textures"/>
+ <menu_item_check label="Ortamı Devre Dışı Bırak" name="Disable Ambient"/>
+ <menu_item_check label="Güneş Işığını Devre Dışı Bırak" name="Disable Sunlight"/>
+ <menu_item_check label="Yerel Işıkları Devre Dışı Bırak" name="Disable Local Lights"/>
<menu_item_check label="Tam Çöz. Dokular" name="Rull Res Textures"/>
<menu_item_check label="Eklenmiş Işıkları İşle" name="Render Attached Lights"/>
<menu_item_check label="Eklenmiş Parçacıkları İşle" name="Render Attached Particles"/>
@@ -481,6 +469,7 @@
<menu_item_call label="Etek" name="Skirt"/>
<menu_item_call label="Alfa" name="Alpha"/>
<menu_item_call label="Dövme" name="Tattoo"/>
+ <menu_item_call label="Evrensel" name="Universal"/>
<menu_item_call label="Fizik" name="Physics"/>
<menu_item_call label="Tüm Giysiler" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
index 448202df87..486f76a29a 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="DeÄŸiÅŸtir" name="wear_replace"/>
<menu_item_call label="Giy" name="wear_wear"/>
<menu_item_call label="Ekle" name="wear_add"/>
+ <menu_item_call label="Dokun" name="touch" />
<menu_item_call label="Çıkar / Ayır" name="take_off_or_detach"/>
<menu_item_call label="Ayır" name="detach"/>
<context_menu label="Åžuna ekle" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
index 438e580cd3..1594cf3afb 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="Dış Görünümü Düzenle" name="edit"/>
+ <menu_item_call label="Dokun" name="touch"/>
+ <menu_item_call label="Düzenle" name="edit_item"/>
+ <menu_item_call label="Dış Görünümü Düzenle" name="edit_outfit"/>
<menu_item_call label="Çıkar" name="takeoff"/>
<menu_item_call label="Dış görünüm listesini panoya kopyala" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
index 1db95c17e1..56397c8628 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="Dokun" name="touch_attach"/>
<menu_item_call label="Çıkar" name="take_off"/>
<menu_item_call label="Ayır" name="detach"/>
- <menu_item_call label="Dış Görünümü Düzenle" name="edit"/>
+ <menu_item_call label="Dış Görünümü Düzenle" name="edit_outfit"/>
<menu_item_call label="Düzenle" name="edit_item"/>
<menu_item_call label="Orijinali Göster" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 13867cf5b8..5403a78f22 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -266,6 +266,10 @@ Seçili Sakinlere değişiklik yapma hakkı vermek istiyor musunuz?
Seçili Sakinlerin değişiklik yapma hakkını iptal etmek istiyor musunuz?
<usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
</notification>
+ <notification name="GroupNameLengthWarning">
+ Bir grup adı [MIN_LEN] ile [MAX_LEN] karakter olmalıdır.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
<notification name="UnableToCreateGroup">
Grup oluşturulamıyor.
[MESSAGE]
@@ -360,7 +364,7 @@ Devam etmek istiyor musunuz?
Bu gruba katılmak için yeterli L$&apos;na sahip değilsiniz.
</notification>
<notification name="CreateGroupCost">
- Bu grubu oluşturmanın maliyeti: L$ 100.
+ Bu grubu oluşturmak L$[COST]'dır.
Grupların birden fazla üyeye sahip olması gereklidir, aksi takdirde grup kalıcı olarak silinir.
Lütfen 48 saat içinde diğer üyeleri davet edin.
<usetemplate canceltext="İptal" name="okcancelbuttons" notext="İptal" yestext="L$ 100 ödeyerek grubu oluştur"/>
@@ -501,6 +505,9 @@ Ortamı sadece bir yüze yerleştirmek için, Yüz Seç&apos;i seçin ve ardınd
<notification name="ErrorEncodingSnapshot">
Anlık görüntü kodlanırken hata oluştu.
</notification>
+ <notification name="ErrorCannotAffordUpload">
+ Bu nesneyi yüklemek için L$[COST] ' a ihtiyacınız var.
+ </notification>
<notification name="ErrorPhotoCannotAfford">
Envanterinize bir fotoğraf kaydedebilmek için [COST] L$ paraya ihtiyacınız var. L$ satın alabilir veya bunun yerine fotoğrafı bilgisayarınıza kaydedebilirsiniz.
</notification>
@@ -1739,11 +1746,14 @@ Gruptan ayrılmak istiyor musunuz?
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="GroupLimitInfo">
- Temel hesaplar için grup limiti [MAX_BASIC], [https://secondlife.com/premium/ özel] hesaplar
-içinse [MAX_PREMIUM] olarak belirlenmiştir.
-Hesabınızı indirgediyseniz, daha fazla gruba katılmak için önce grup sayınızı [MAX_BASIC] grubun altına düşürmelisiniz.
-
-[https://secondlife.com/my/account/membership.php Şimdi yükselt!]
+ Temel üyelikler [MAX_BASIC]'a kadar katılım sağlayabilir.
+Premium üyelikler [MAX_PREMIUM] 'a kadar izinlidir. [https://secondlife.com/my/account/membership.php? Daha fazla bilgi alın ya da üyeiliğinizi yükseltin]
+ <usetemplate name="okbutton" yestext="Kapat"/>
+ </notification>
+ <notification name="GroupLimitInfoPlus">
+ Temel üyelik sahibi yerleşimciler [MAX_BASIC]'a kadar olan gruplara katılabilir.
+Premium üyeler [MAX_PREMIUM] 'a kadar izinlidir. Premium Plus üyeler [MAX_PREMIUM_PLUS] 'a kadar izinlidir.
+[https://secondlife.com/my/account/membership.php? Daha fazla bilgi alın ya da üyeiliğinizi yükseltin]
<usetemplate name="okbutton" yestext="Kapat"/>
</notification>
<notification name="KickUser">
@@ -1960,6 +1970,11 @@ Binlerce bölgeyi değiştirecek ve alan sunucusunu kesintiye uğratacaktır.
Bu seçeneğin onay işaretini kaldırmak, parsel sahiplerinin rahatsızlık veren oyuncuları bunu yapmasını engellemek, gizliliği sürdürmek ve yaşı tutmayan sakinleri yetişkin içeriklerden korumak için ekledikleri kısıtlamaları kaldırabilir. Lütfen gerekli olduğunda parsel sahiplerinizle tartışın.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ Bu seçeneğin onay işaretinin kaldırılması, parsel sahiplerinin kendi parsellerine eklemiş oldukları tüm özel ortamları kaldırır. Lütfen gerektiğinde parsel sahiplerinizle görüşün.
+Devam etmek istiyor musunuz?
+ <usetemplate name="okcancelbuttons" notext="İptal Et" yestext="Tamam"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
<usetemplate name="okbutton" yestext="Tamam"/>
@@ -2438,7 +2453,15 @@ Diğer kişilerin bu konuma kolayca erişmesini sağlamak için bu adrese bir we
Bu gün döngüsü dosyası kayıp bir gökyüzü dosyasına başvuruda bulunuyor: [SKY].
</notification>
<notification name="WLRegionApplyFail">
- Üzgünüz, bu ayarlar bölgeye uygulanamadı. Bölgeden ayrılmak ve sonra geri dönmek sorunu çözebilir. Gösterilen neden şuydu: [FAIL_REASON]
+ Üzgünüz, ayarlar bölgeye uygulanamadı. Neden: [FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ Bir Yerel doku [FIELD] alanındaki [TRACK] rotasında, #[FRAMENO] ([FRAME]%) çerçevesinde kullanılıyor.
+Ayarlar yerel dokular kullanılarak kaydedilemez.
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ Bir yerel doku [FIELD] alanında kullanılıyor.
+Ayarlar yerel dokular kullanılarak kaydedilemez.
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
Bu gün döngüsündeki son anahtar silinemedi çünkü boş bir gün döngünüz olamaz. Son kalan anahtarı silmek ve yenisini oluşturmaya kalkışmak yerine bunu değiştirmelisiniz.
@@ -3290,6 +3313,22 @@ Güvenliğiniz için birkaç saniye engellenecek.
Sesli sohbetiniz moderatör tarafından engellendi.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
+ <notification name="FailedToGetBenefits">
+ Maalesef, bu oturumun avantajlarıyla ilgili bilgilere ulaşamıyoruz. Normal prodüksiyon ortamında yaşanmaması gereken bir durumdur. Lütfen destek ekibiyle iletişime geçin. Bu oturum normal bir şekilde çalışmayacaktır, yeniden başlatmanızı öneririz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="BulkUploadCostConfirmation">
+ Bu, toplam tutarı L$[COST] olan [COUNT] nesne yükleyecektir. Bu yüklemeye devam etmek istiyor musunuz?
+ <usetemplate name="okcancelbuttons" notext="İptal" yestext="Karşıya Yükle"/>
+ </notification>
+ <notification name="BulkUploadNoCompatibleFiles">
+ Seçili dosyalar aynı anda yüklenemez.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="BulkUploadIncompatibleFiles">
+ Seçili bazı dosyalar aynı anda yüklenemez.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
<notification name="UploadCostConfirmation">
Bu karşıya yükleme işleminin maliyeti L$[PRICE] olacak, karşıya yüklemeye devam etmek istiyor musunuz?
<usetemplate name="okcancelbuttons" notext="İptal" yestext="Karşıya Yükle"/>
@@ -4382,4 +4421,75 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
[REASON]
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
+ <notification name="FailedToFindSettings">
+ [NAME] ile ilgili ayarlar veritabanından yüklenemedi.
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ Bu değişiklikler ortama uygulanamıyor.
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ Bu değişiklikler ortama uygulanamıyor.
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ Bu Bölge ortam ayarlarını desteklemiyor.
+ </notification>
+ <notification label="Dış Görünümü Kaydet" name="SaveSettingAs">
+ Geçerli ortam ayarlarını farklı kaydet:
+ <form name="form">
+ <input name="message">
+ [DESC] (yeni)
+ </input>
+ <button name="OK" text="Tamam"/>
+ <button name="Cancel" text="İptal Et"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ Eski Windlight ayarları [NAME], [FILE] kaynağından içeri aktarılamıyor.
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ Bu parsele ait ortam ayarlanamıyor.
+Lütfen değişiklik yapma hakkına sahip olduğunuz bir parsel girin veya seçin.
+ </notification>
+ <notification name="SettingsUnsuported">
+ Ayarlar bu bölgede desteklenmiyor.
+Lütfen ayarların etkin olduğu bir bölgeye gidin ve eyleminizi yeniden deneyin.
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ &quot;[NAME]&quot; adlı bu [TYPE] öğesinde yaptığınız değişiklikleri kaybetmek üzeresiniz.
+Devam etmek istediÄŸinizden emin misiniz?
+ <usetemplate ignoretext="Değişiklikleri kaybetmek istediğinizden emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ Uygulanan ayarlarınızın tümünü kaldırmak üzeresiniz.
+Devam etmek istediÄŸinizden emin misiniz?
+ <usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ Uygulanan Kişisel aydınlatma ayarlarınızın tümünü kaldırmak üzeresiniz.
+Devam etmek istediÄŸinizden emin misiniz?
+ <usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ Aktarılamayan ayarları bu gün döngüsüne aktarmak üzeresiniz. Bu işleme devam etmeniz düzenlemekte olduğunuz ayarların da aktarılamaz olmasına neden olacaktır.
+
+Bu değişiklik geri alınamaz.
+
+Devam etmek istediÄŸinizden emin misiniz?
+ <usetemplate ignoretext="Ayarları aktarılamaz hale getirmek istediğinizden emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ Ayarları doğrudan kütüphaneden düzenleyemezsiniz.
+Lütfen kendi envanterinize kopyalayın ve yeniden deneyin.
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ Bu ayarlarla ilgili bir sorunla karşılaştık. Bu ayarlar şu anda kaydedilemiyor veya uygulanamıyor.
+ </notification>
+ <notification name="TrackLoadFailed">
+ Rota [TRACK] hedefine yüklenemiyor.
+ </notification>
+ <notification name="TrackLoadMismatch">
+ Rota [TRACK1] kaynağından [TRACK2] hedefine yüklenemiyor.
+ </notification>
</notifications>
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 7584b754f1..fc444f21f6 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
@@ -47,7 +47,7 @@
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
<layout_panel name="show_on_map_btn_lp">
- <button label="İptal" name="cancel_btn"/>
+ <button label="İptal Et" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
index 7f5590a485..fb97f1e1ce 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="Baş Dövmesi" name="Head Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
- <texture_picker label="Üst Gövde Dövmesi" name="Upper Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
- <texture_picker label="Alt Gövde Dövmesi" name="Lower Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
- <color_swatch label="Renk/Ton" name="Color/Tint" tool_tip="Renk seçiciyi açmak için tıklayın"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="Baş Dövmesi" name="Head Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Üst Gövde Dövmesi" name="Upper Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Alt Gövde Dövmesi" name="Lower Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <color_swatch label="Renk/Ton" name="Color/Tint" tool_tip="Renk seçiciyi açmak için tıklayın"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_universal.xml b/indra/newview/skins/default/xui/tr/panel_edit_universal.xml
new file mode 100644
index 0000000000..ef10307d11
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="Baş Dövmesi" name="Head Universal Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Üst Gövde Dövmesi" name="Upper Universal Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Alt Gövde Dövmesi" name="Lower Universal Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Etek Dövmesi" name="Skirt Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Saç Dövmesi" name="Hair Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Göz Dövmesi" name="Eyes Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Sol Kol Dövmesi" name="Left Arm Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Sol Bacak Dövmesi" name="Left Leg Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Yedek 1 Dövme" name="Aux1 Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Yedek 2 Dövme" name="Aux2 Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <texture_picker label="Yedek 3 Dövme" name="Aux3 Tattoo" tool_tip="Bir resim seçmek için tıklayın"/>
+ <color_swatch label="Renk/Ton" name="Color/Tint" tool_tip="Renk seçiciyi açmak için tıklayın"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml b/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
index 7a4a09aaed..7880de8e7d 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
Dövme Düzenleniyor
</string>
+ <string name="edit_universal_title">
+ Evrensel Düzenleniyor
+ </string>
<string name="edit_physics_title">
Fizik Düzenleniyor
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
Dövme:
</string>
+ <string name="universal_desc_text">
+ Evrensel:
+ </string>
<string name="physics_desc_text">
Fizik:
</string>
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
index 4b911c9ce6..d9e79d171c 100644
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ b/indra/newview/skins/default/xui/tr/panel_me.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Profilim" name="panel_me">
- <panel label="SEÇMELERİM" name="panel_picks"/>
+ <panel label="SEÇTİKLERİM" name="panel_picks"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
deleted file mode 100644
index a947eee150..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Öğeleri vitrininizde satışa hazırlamak için sürükleyip buraya bırakın"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 29ca4772fd..25d29fcbb5 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -18,7 +18,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<string name="no_groups_msg" value="Katılacak Gruplar mı arıyorsunuz? [secondlife:///app/search/groups Ara] deneyin."/>
<string name="MiniMapToolTipMsg" value="[REGION](Haritayı açmak için çift tıkla, yatay hareket için shift çek)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Işınlamak için çift tıkla, yatay hareket için shift çek)"/>
- <string name="GroupCountWithInfo" value="[COUNT] gruba üyesiniz, daha [REMAINING] gruba üye olabilirsiniz. [secondlife:/// Daha fazlasını mı istiyorsunuz?]"/>
+ <string name="GroupCountWithInfo" value="[COUNT] gruba üyesin ve [REMAINING] daha gruba üye olabilirsin. [secondlife:/// Limitini arttır]"/>
<tab_container name="tabs">
<panel label="YAKIN" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -51,7 +51,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<dnd_button name="minus_btn" tool_tip="Seçilen gruptan ayrıl"/>
</panel>
<text name="groupcount">
- [COUNT] gruba üyesiniz, daha [REMAINING] gruba üye olabilirsiniz.
+ [COUNT] gruba üyesin ve [REMAINING] daha gruba üye olabilirsin.
</text>
</panel>
<panel label="SON" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/tr/panel_region_environment.xml b/indra/newview/skins/default/xui/tr/panel_region_environment.xml
index b5f505f25f..d375203cf6 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Ortam" name="panel_env_info">
- <text name="water_settings_title">
- Bölgenize gelen tüm ziyaretçilerin görmesini istediğiniz Su ve Gökyüzü/Gündüz Döngüsü Ayarlarını seçin. Ek bilgi
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="Second Life varsayılanını kullan" name="use_sl_default_settings"/>
- <radio_item label="Aşağıdaki ayarları kullan" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- Su Ayarı
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-Bir ön ayar seçin-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- Gökyüzü / Gün Döngüsü
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="Sabit gökyüzü" name="my_sky_settings"/>
- <radio_item label="Gün döngüsü" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-Bir ön ayar seçin-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-Bir ön ayar seçin-" name="item0"/>
- </combo_box>
- </panel>
- <button label="Uygula" name="apply_btn"/>
- <button label="İptal Et" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ Varsayılan Ayarları Kullan
+ </string>
+ <string name="str_label_use_region">
+ Bölge Ayarlarını Kullan
+ </string>
+ <string name="str_altitude_desription">
+ Gökyüzü [INDEX]([ALTITUDE] m)
+ </string>
+ <string name="str_no_parcel">
+ Parsel seçilmedi. Ortam ayarları devre dışı.
+ </string>
+ <string name="str_cross_region">
+ Ortam ayarları bölge sınırları dahilinde kullanılamıyor.
+ </string>
+ <string name="str_legacy">
+ Ortam ayarları bu bölgede kullanılamıyor.
+ </string>
+ <string name="str_disallowed">
+ Gayrimenkul yöneticisi bu bölgede parsel ortamlarını değiştirmeye izin vermiyor.
+ </string>
+ <string name="str_too_small">
+ Parselin bir ortamı desteklemesi için en az 128 metrekare olması gerekir.
+ </string>
+ <string name="str_empty">
+ (boÅŸ)
+ </string>
+ <string name="str_region_env">
+ (bölge ortamı)
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="Envanteri Kullan" name="btn_select_inventory"/>
+ <button label="Özelleştir" name="btn_edit"/>
+ <check_box label="Parsel Sahipleri Ortamı Geçersiz Kılabilir" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] (% [PRC])
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ Gökyüzü [INDEX]
+ [ALTITUDE] m
+ </text>
+ <line_editor name="edt_invname_alt1">
+ Bilinmiyor
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="Geçerli gökyüzü olarak seçmek için Envanterden bir ayarı bu hedef kutuya sürükleyin."/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ Gökyüzü [INDEX]
+ [ALTITUDE] m
+ </text>
+ <line_editor name="edt_invname_alt2">
+ Bilinmiyor
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="Geçerli gökyüzü olarak seçmek için Envanterden bir ayarı bu hedef kutuya sürükleyin."/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ Gökyüzü [INDEX]
+ [ALTITUDE] m
+ </text>
+ <line_editor name="edt_invname_alt3">
+ Bilinmiyor
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="Geçerli gökyüzü olarak seçmek için Envanterden bir ayarı bu hedef kutuya sürükleyin."/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ Zemin
+ </text>
+ <line_editor name="edt_invname_ground">
+ Bilinmiyor
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="Zemin seviyesinde gökyüzü olarak seçmek için Envanterden bir ayarı bu hedef kutuya sürükleyin."/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ Su
+ </text>
+ <line_editor name="edt_invname_water">
+ Bilinmiyor
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="Geçerli su olarak seçmek için Envanterden bir ayarı bu hedef kutuya sürükleyin."/>
+ </panel>
+ <button label="Sıfırla" name="btn_rst_altitudes" tool_tip="Varsayılan irtifalara sıfırla"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/tr/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..9bc23a5507
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Atmosfer ve Aydınlatma" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/tr/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..5dd31546cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Bulutlar" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/tr/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..1d2aa30921
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="YoÄŸunluk" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Rayleigh Üstel Terim:" name="rayleigh_exponential"/>
+ <slider label="Rayleigh Üstel Skala:" name="rayleigh_exponential_scale"/>
+ <slider label="Rayleigh Lineer Terim:" name="rayleigh_linear"/>
+ <slider label="Rayleigh Sabit Terim:" name="rayleigh_constant"/>
+ <slider label="Rayleigh Maks. İrtifa:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Mie Üstel Terim:" name="mie_exponential"/>
+ <slider label="Mie Üstel Skala:" name="mie_exponential_scale"/>
+ <slider label="Mie Lineer Terim:" name="mie_linear"/>
+ <slider label="Mie Sabit Terim:" name="mie_constant"/>
+ <slider label="Mie Anizotropi Faktörü:" name="mie_aniso_factor"/>
+ <slider label="Mie Maks. İrtifa:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Absorpsiyon Üstel Terim:" name="absorption_exponential"/>
+ <slider label="Absorpsiyon Üstel Skala:" name="absorption_exponential_scale"/>
+ <slider label="Absorpsiyon Lineer Terim:" name="absorption_linear"/>
+ <slider label="Absorpsiyon Sabit Terim:" name="absorption_constant"/>
+ <slider label="Absorpsiyon Maks. İrtifa:" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/tr/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..44fccb594d
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Güneş ve Ay" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="İşareti Göster" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="İşareti Göster" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_settings_water.xml b/indra/newview/skins/default/xui/tr/panel_settings_water.xml
new file mode 100644
index 0000000000..9537a2b494
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Su" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ Fresnel Dengeleme:
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_tools_texture.xml b/indra/newview/skins/default/xui/tr/panel_tools_texture.xml
index 1324e2cc36..baf53a7af4 100644
--- a/indra/newview/skins/default/xui/tr/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/tr/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Doku" name="Texture">
- <panel.string name="string repeats per meter">
- Metrede Kaç Kez Tekrarlandığı
- </panel.string>
- <panel.string name="string repeats per face">
- Bir Yüzde Kaç Kez Tekrarlandığı
- </panel.string>
<text name="color label">
Renk
</text>
@@ -114,4 +108,5 @@
<spinner label="Yatay ofset" name="shinyOffsetU"/>
<spinner label="Dikey ofset" name="shinyOffsetV"/>
<check_box initial_value="false" label="Planar yüzleri hizala" name="checkbox planar align" tool_tip="Tüm seçili yüzeylerdeki dokuları son seçili yüzdekiyle hizalar. Planar doku eşleştirmesi gerektirir."/>
+ <button label="Hizala" label_selected="Geçerli doku katmanlarına hizala" name="button align textures" tool_tip="Geçerli doku katmanlarına hizala"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/role_actions.xml b/indra/newview/skins/default/xui/tr/role_actions.xml
index 5e830bddd5..3ac4a7b19f 100644
--- a/indra/newview/skins/default/xui/tr/role_actions.xml
+++ b/indra/newview/skins/default/xui/tr/role_actions.xml
@@ -33,6 +33,7 @@
<action description="Müziği &amp; ortam ayarlarını değiştir" longdescription="Akış müziğini ve film ayarlarını Arazi Hakkında &gt; Ortam sekmesinden değiştirin." name="land change media" value="20"/>
<action description="&apos;Yüzeyi Düzenle&apos; seçeneğini Aç/Kapa" longdescription="&apos;Yüzeyi Düzenle&apos; seçeneğini açın/kapatın. *UYARI* Arazi Hakkında &gt; Seçenekler sekmesi &gt; Yüzeyi Düzenle seçeneği, herhangi bir kişinin arazinizin şeklini değiştirmesine, Linden bitkileri yerleştirmesine ve bu bitkilerin yerlerini değiştirmesine izin verir. Bu Yeteneği atamadan önce ne yaptığınızı bildiğinizden emin olun. Yüzey düzenleme seçeneği Arazi Hakkında &gt; Seçenekler sekmesinden açılıp kapanır." name="land edit" value="21"/>
<action description="Arazi Hakkında &gt; Seçenekler sekmesindeki çeşitli ayarları Aç/Kapa" longdescription="&apos;Güvenli (hasar yok)&apos;, &apos;Uç&apos; ve diğer Second Life Sakinlerinin &apos;Yüzeyi Düzenle&apos;, &apos;İnşa Et&apos;, &apos;Yer İmleri Oluştur&apos; ve &apos;Komut Dosyalarını Çalıştır&apos; yeteneklerini grubun sahip olduğu arazi üzerinde kullanmalarına izin verme tercihini Arazi Hakkında &gt; Seçenekler sekmesinden açın/kapayın." name="land options" value="22"/>
+ <action description="Ortam ayarlarını ve gün döngüsünü değiştirin." longdescription="Arazi Hakkında &gt; Ortam sekmesinden ortam ayarlarını ve gün döngüsünü değiştirin." name="land change environment" value="46"/>
</action_set>
<action_set description="Bu Yeteneklere Üyelerin grubun sahip olduğu parseller üzerindeki kısıtlamaları geçmesine izin veren güçler de dahildir." name="Parcel Powers">
<action description="&apos;Yüzeyi Düzenle&apos; yeteneğine her zaman izin ver" longdescription="Bu Yeteneğe sahip olan bir Roldeki Üyeler, Arazi Hakkında &gt; Seçenekler sekmesinde kapalı olsa da grubun sahip olduğu parsel üzerinde yüzey düzenleme yapabilir." name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 27f3c4d4d9..56fad978f5 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -639,6 +639,15 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="BUTTON_HELP">
Yardımı Göster
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ Bu türe ait öğeler bu bölgedeki
+not kartlarına eklenemez.
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ Sadece kısıtlamasız &apos;sonraki sahip&apos;
+izinlerini içeren öğeler not
+kartlarına eklenebilir.
+ </string>
<string name="Searching">
Arıyor...
</string>
@@ -715,6 +724,18 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
Karşıya yükleme talebinde hata. Bu sorunu çözmek için lütfen
http://secondlife.com/support adresini ziyaret edin.
</string>
+ <string name="SettingValidationError">
+ [NAME] ayarlarının içeri aktarılması için doğrulama başarısız oldu
+ </string>
+ <string name="SettingImportFileError">
+ [FILE] dosyası açılamadı
+ </string>
+ <string name="SettingParseFileError">
+ [FILE] dosyası açılamadı
+ </string>
+ <string name="SettingTranslateError">
+ Eski Windlight [NAME] çevrilemedi
+ </string>
<string name="texture">
doku
</string>
@@ -790,6 +811,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="symbolic folder link">
klasör bağlantısı
</string>
+ <string name="settings blob">
+ ayarlar
+ </string>
<string name="mesh">
örgü
</string>
@@ -1120,6 +1144,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="ForceSitAvatar">
Avatarınızı oturmaya zorlayın
</string>
+ <string name="ChangeEnvSettings">
+ Ortam ayarlarınızı değiştirin
+ </string>
<string name="NotConnected">
Bağlı Değil
</string>
@@ -1271,6 +1298,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="tattoo">
Dövme
</string>
+ <string name="universal">
+ Evrensel
+ </string>
<string name="physics">
Fizik
</string>
@@ -1313,6 +1343,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="tattoo_not_worn">
Giyilmemiş dövme
</string>
+ <string name="universal_not_worn">
+ Evrensel giyilmiyor
+ </string>
<string name="physics_not_worn">
GiyilmemiÅŸ fizik
</string>
@@ -1364,6 +1397,9 @@ http://secondlife.com/support adresini ziyaret edin.
<string name="create_new_tattoo">
Yeni dövme oluştur
</string>
+ <string name="create_new_universal">
+ Yeni evrensel oluÅŸtur
+ </string>
<string name="create_new_physics">
Yeni fizik oluÅŸtur
</string>
@@ -1607,11 +1643,14 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="MarketplaceUpdating">
güncelleniyor...
</string>
+ <string name="UploadFeeInfo">
+ Ücret, üyelik seviyene göre belirlenir. Yüksek seviyelere daha düşük ücretler uygulanır. [https://secondlife.com/my/account/membership.php? Daha fazla bilgi al]
+ </string>
<string name="Open landmarks">
- Açık yer imleri
+ Açık alanlar
</string>
<string name="Unconstrained">
- Kısıtsız
+ Serbest
</string>
<string name="no_transfer" value="(aktarım yok)"/>
<string name="no_modify" value="(deÄŸiÅŸtirme yok)"/>
@@ -2511,6 +2550,27 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="RegionSettings">
Bölge Ayarları
</string>
+ <string name="NoEnvironmentSettings">
+ Bu Bölge ortam ayarlarını desteklemiyor.
+ </string>
+ <string name="EnvironmentSun">
+ Güneş
+ </string>
+ <string name="EnvironmentMoon">
+ Ay
+ </string>
+ <string name="EnvironmentBloom">
+ Bahar
+ </string>
+ <string name="EnvironmentCloudNoise">
+ Bulut Gürültüsü
+ </string>
+ <string name="EnvironmentNormalMap">
+ Normal Harita
+ </string>
+ <string name="EnvironmentTransparent">
+ Saydam
+ </string>
<string name="ClassifiedClicksTxt">
Tıklamalar: [TELEPORT] ışınlama, [MAP] harita, [PROFILE] profil
</string>
@@ -4725,6 +4785,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="New Tattoo">
Yeni Dövme
</string>
+ <string name="New Universal">
+ Yeni Evrensel
+ </string>
<string name="New Physics">
Yeni Fizik
</string>
@@ -4851,6 +4914,15 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="Female - Wow">
Kadın - Vay be
</string>
+ <string name="New Daycycle">
+ Yeni Gün döngüsü
+ </string>
+ <string name="New Water">
+ Yeni Su
+ </string>
+ <string name="New Sky">
+ Yeni Gökyüzü
+ </string>
<string name="/bow">
/selamlama
</string>
@@ -5023,6 +5095,9 @@ Hizmetle ilişkili bilinen bir sorun olup olmadığını görmek için lütfen h
<string name="Chat">
Sohbet
</string>
+ <string name="BaseMembership">
+ Temel
+ </string>
<string name="DeleteItems">
Seçili öğeler silinsin mi?
</string>
@@ -5391,6 +5466,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="BeaconMedia">
Ortam işaretleri gösteriliyor (beyaz)
</string>
+ <string name="BeaconSun">
+ Güneş yönü işareti (turuncu) görüntüleniyor
+ </string>
+ <string name="BeaconMoon">
+ Ay yönü işareti (mor) görüntüleniyor
+ </string>
<string name="ParticleHiding">
Parçacıklar Gizleniyor
</string>
@@ -5418,6 +5499,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Command_Destinations_Label">
Hedef Konum
</string>
+ <string name="Command_Environments_Label">
+ Ortamlarım
+ </string>
+ <string name="Command_Facebook_Label">
+ Facebook
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5511,6 +5598,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Command_Destinations_Tooltip">
İlgilendiğiniz hedef konumlar
</string>
+ <string name="Command_Environments_Tooltip">
+ Ortamlarım
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ Facebook&apos;ta Yayınla
+ </string>
<string name="Command_Flickr_Tooltip">
Flickr&apos;a yükle
</string>
@@ -5706,6 +5799,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="ExperiencePermission12">
deneyim izinlerini otomatik olarak kabul et
</string>
+ <string name="ExperiencePermission16">
+ avatarınızı oturmaya zorlayın
+ </string>
+ <string name="ExperiencePermission17">
+ ortam ayarlarınızı değiştirin
+ </string>
<string name="ExperiencePermissionShortUnknown">
bilinmeyen bir işlem gerçekleştirdi: [Permission]
</string>
@@ -5730,6 +5829,12 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="ExperiencePermissionShort12">
İzin
</string>
+ <string name="ExperiencePermissionShort16">
+ Otur
+ </string>
+ <string name="ExperiencePermissionShort17">
+ Ortam
+ </string>
<string name="logging_calls_disabled_log_empty">
Sohbetlerin günlüğü tutulmuyor. Bir günlük tutmaya başlamak için, Tercihler &gt; Sohbet altında &quot;Kaydet: Sadece günlük&quot; veya &quot;Kaydet: Günlük ve dökümler&quot; seçimini yapın.
</string>
diff --git a/indra/newview/skins/default/xui/zh/floater_about_land.xml b/indra/newview/skins/default/xui/zh/floater_about_land.xml
index 1164722abf..bb680f822e 100644
--- a/indra/newview/skins/default/xui/zh/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about_land.xml
@@ -474,5 +474,6 @@
</panel>
</panel>
<panel label="體驗" name="land_experiences_panel"/>
+ <panel label="環境" name="land_environment_panel"/>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_adjust_environment.xml b/indra/newview/skins/default/xui/zh/floater_adjust_environment.xml
new file mode 100644
index 0000000000..192c429430
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_adjust_environment.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_adjust_snapshot" title="個人照明">
+ <layout_stack name="outer_stack">
+ <layout_panel name="env_controls">
+ <layout_stack name="settings_stack">
+ <layout_panel>
+ <button label="é‡è¨­" name="btn_reset" tool_tip="關閉並é‡è¨­çˆ²å…±äº«ç’°å¢ƒ"/>
+ <text name="cloud_map_label">
+ 雲彩圖åƒï¼š
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <text name="label">
+ 太陽:
+ </text>
+ <check_box label="顯示指標" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box label="顯示指標" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_beacons.xml b/indra/newview/skins/default/xui/zh/floater_beacons.xml
index 83e10804d6..4df8c8f14b 100644
--- a/indra/newview/skins/default/xui/zh/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/zh/floater_beacons.xml
@@ -18,5 +18,7 @@
<check_box label="è²éŸ³ä¾†æº" name="sounds"/>
<check_box label="例å­ä¾†æº" name="particles"/>
<check_box label="媒體來æº" name="moapbeacon"/>
+ <check_box label="太陽" name="sun"/>
+ <check_box label="月亮" name="moon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
index dbf4a21416..3729aa7620 100644
--- a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
@@ -21,6 +21,7 @@
<icon name="icon_script" tool_tip="腳本"/>
<icon name="icon_sound" tool_tip="è²éŸ³"/>
<icon name="icon_texture" tool_tip="æè³ª"/>
+ <icon name="icon_setting" tool_tip="環境設定"/>
<button label="√ 全部" name="check_all"/>
<button label="清除" label_selected="無" name="check_none"/>
<text name="newperms">
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
index fcf2800728..41c8c26ccc 100644
--- a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
@@ -59,8 +59,7 @@
</text>
<button label="ç«‹å³è³¼è²·" name="buy_btn"/>
<button label="å–æ¶ˆ" name="cancel_btn"/>
- <text name="info_cannot_buy">
+ <floater.string name="info_cannot_buy">
無法購買
- </text>
- <button label="繼續到網é " name="error_web"/>
+ </floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml
deleted file mode 100644
index 4aafb31952..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<floater name="Delete Env Preset" title="刪除環境自訂é…ç½®">
- <string name="title_water">
- 刪除水的自訂é…ç½®
- </string>
- <string name="title_sky">
- 刪除天空自訂é…ç½®
- </string>
- <string name="title_day_cycle">
- 刪除日循環
- </string>
- <string name="label_water">
- 自訂é…置:
- </string>
- <string name="label_sky">
- 自訂é…置:
- </string>
- <string name="label_day_cycle">
- 日循環:
- </string>
- <string name="msg_confirm_deletion">
- 確定è¦åˆªé™¤æ‰€é¸è‡ªè¨‚é…置?
- </string>
- <string name="msg_sky_is_referenced">
- 無法刪除日循環有所指涉的自訂é…置。
- </string>
- <string name="combo_label">
- -鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-
- </string>
- <text name="label">
- 自訂é…置:
- </text>
- <button label="刪除" name="delete"/>
- <button label="å–æ¶ˆ" name="cancel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/zh/floater_edit_ext_day_cycle.xml
new file mode 100644
index 0000000000..cdcf0a685e
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_edit_ext_day_cycle.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="env_edit_extdaycycle" title="編輯日循環">
+ <string name="title_new">
+ 新建一個日循環
+ </string>
+ <string name="title_edit">
+ 編輯日循環
+ </string>
+ <string name="hint_new">
+ 為日循環定å,調整å„項控制確定細節,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="hint_edit">
+ è‹¥è¦ç·¨è¼¯ä½ çš„æ—¥å¾ªç’°ï¼Œè«‹èª¿æ•´ä¸‹æ–¹å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="time_label">
+ ([HH]:[MM])
+ </string>
+ <string name="sky_track_label">
+ 天空[ALT]
+ </string>
+ <string name="sky_label">
+ 天空
+ </string>
+ <string name="water_label">
+ æ°´æ–‡
+ </string>
+ <string name="commit_parcel">
+ 套用到地段
+ </string>
+ <string name="commit_region">
+ 套用到地å€
+ </string>
+ <layout_stack name="outer_stack">
+ <layout_panel name="name_and_import">
+ <text name="label">
+ 日循環å稱:
+ </text>
+ <button label="匯入" name="btn_import" tool_tip="從ç£ç¢ŸåŒ¯å…¥èˆŠè¨­å®šã€‚"/>
+ </layout_panel>
+ <layout_panel name="content">
+ <layout_stack name="content_stack">
+ <layout_panel name="timeline_track_selection">
+ <panel name="timeline_layers">
+ <button label="天空 4" name="sky4_track"/>
+ <button label="天空 3" name="sky3_track"/>
+ <button label="天空 2" name="sky2_track"/>
+ <button label="åœ°é¢æ°´å¹³" name="sky1_track"/>
+ <button label="æ°´æ–‡" name="water_track"/>
+ </panel>
+ <panel name="timeline">
+ <text name="p0" value="0%[DSC]"/>
+ <text name="p1" value="25%[DSC]"/>
+ <text name="p2" value="50%[DSC]"/>
+ <text name="p3" value="75%[DSC]"/>
+ <text name="p4" value="100%[DSC]"/>
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleFrames"/>
+ <text name="current_time" value="[PRCNT]%[DSC]"/>
+ <layout_stack>
+ <layout_panel>
+ <button label="複製軌跡來æºï¼š" name="copy_track"/>
+ <button label="載入軌跡來æºï¼š" name="load_track"/>
+ <button label="清除軌跡" name="clear_track"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="progress_control">
+ <layout_panel name="skip_back">
+ <button name="skip_back_btn" tool_tip="逿­¥å¾Œé€€"/>
+ </layout_panel>
+ <layout_panel name="skip_forward">
+ <button name="skip_forward_btn" tool_tip="逿­¥å‰é€²"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel>
+ <button label="新增[FRAME]" name="add_frame"/>
+ <button label="載入[FRAME]" name="btn_load_frame"/>
+ <button label="刪除[FRAME]" name="delete_frame"/>
+ </layout_panel>
+ </layout_stack>
+ </panel>
+ </layout_panel>
+ <layout_panel name="frame_edit_controls">
+ <text name="icn_lock_edit">
+ å¾žä¸Šæ–¹çš„æ™‚é–“ç·šé¸æ“‡ä¸€å€‹é—œéµå¹€ä»¥ç·¨è¼¯è¨­å®šã€‚
+ </text>
+ </layout_panel>
+ <layout_panel name="frame_settings_water">
+ <tab_container name="water_tabs">
+ <panel label="æ°´æ–‡" name="water_panel"/>
+ </tab_container>
+ </layout_panel>
+ <layout_panel name="frame_settings_sky">
+ <tab_container name="sky_tabs">
+ <panel label="大氣與照明" name="atmosphere_panel"/>
+ <panel label="雲彩" name="clouds_panel"/>
+ <panel label="日與月" name="moon_panel"/>
+ </tab_container>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="buttons">
+ <button label="儲存" name="save_btn"/>
+ <button label="å–æ¶ˆ" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/zh/floater_fixedenvironment.xml
new file mode 100644
index 0000000000..b47b893764
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_fixedenvironment.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Fixed Environment" title="固定環境">
+ <string name="edit_sky">
+ 編輯天空:
+ </string>
+ <string name="edit_water">
+ 編輯水文:
+ </string>
+ <layout_stack name="floater_stack">
+ <layout_panel name="info_panel">
+ <button label="載入" name="btn_load" tool_tip="從收ç´å€è¼‰å…¥ä¸€å€‹è¨­å®š"/>
+ <button label="匯入" name="btn_import" tool_tip="從ç£ç¢ŸåŒ¯å…¥èˆŠè¨­å®šã€‚"/>
+ </layout_panel>
+ <layout_panel name="button_panel">
+ <layout_stack name="button_bar_ls">
+ <layout_panel name="save_btn_lp">
+ <button label="儲存" name="btn_commit"/>
+ </layout_panel>
+ <layout_panel name="revert_btn_lp">
+ <button label="å–æ¶ˆ" name="btn_cancel" tool_tip="æ¢å¾©ä¸Šä¸€å€‹å·²å„²å­˜ç‰ˆæœ¬"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
index 9001615d89..ae05396cc5 100644
--- a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
@@ -12,6 +12,7 @@
<check_box label="è²éŸ³" name="check_sound"/>
<check_box label="æè³ª" name="check_texture"/>
<check_box label="å¿«ç…§" name="check_snapshot"/>
+ <check_box label="設定" name="check_settings"/>
<button label="全部" label_selected="全部" name="All"/>
<button label="ç„¡" label_selected="ç„¡" name="None"/>
<check_box label="固定顯示資料夾" name="check_show_empty"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
deleted file mode 100644
index e6a70a7724..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="商家發件匣">
- <string name="OutboxFolderCount1">
- 1 個資料夾
- </string>
- <string name="OutboxFolderCountN">
- [NUM] 個資料夾
- </string>
- <string name="OutboxImporting">
- 正在傳é€è³‡æ–™å¤¾â€¦
- </string>
- <string name="OutboxInitializing">
- 正在åˆå§‹åŒ–…
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- 載入中…
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- 把物項拖曳到這裡,å¯å»ºç«‹è³‡æ–™å¤¾
- </text>
- </panel>
- <button label="é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="outbox_import_btn" tool_tip="推到我第二人生購物市集的店é¢"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_my_environments.xml b/indra/newview/skins/default/xui/zh/floater_my_environments.xml
new file mode 100644
index 0000000000..2184455dc9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_my_environments.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater label="地點" name="my_environments" title="我的環境">
+ <layout_stack>
+ <layout_panel label="éŽæ¿¾å™¨" name="filter_panel">
+ <check_box label="æ—¥" name="chk_days"/>
+ <check_box label="天空" name="chk_skies"/>
+ <check_box label="æ°´æ–‡" name="chk_water"/>
+ <filter_editor label="éŽæ¿¾ç’°å¢ƒ" name="flt_search"/>
+ </layout_panel>
+ <layout_panel label="環境" name="list_panel">
+ <panel label="pnl_inv_wrap" name="pnl_inv_wrap"/>
+ </layout_panel>
+ <layout_panel>
+ <check_box initial_value="false" label="顯示所有資料夾" name="chk_showfolders"/>
+ </layout_panel>
+ <layout_panel name="pnl_control">
+ <panel label="bottom_panel" name="pnl_bottom">
+ <menu_button name="btn_gear" tool_tip="更多é¸é …"/>
+ <menu_button name="btn_newsettings" tool_tip="製作新的設定"/>
+ <button name="btn_del" tool_tip="ç§»é™¤æ‰€é¸æ“‡çš„物å“"/>
+ </panel>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_perms_default.xml b/indra/newview/skins/default/xui/zh/floater_perms_default.xml
index d4706d8d87..eb432a8bcd 100644
--- a/indra/newview/skins/default/xui/zh/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/zh/floater_perms_default.xml
@@ -37,6 +37,10 @@
<text name="label_12" tool_tip="設定é è¨­æ¬Šé™æ±ºå®šä½•時建立æœè£æˆ–身體部ä½">
å¯ç©¿è£æ‰®
</text>
+ <text name="label_13" tool_tip="設定é è¨­æ¬Šé™æ±ºå®šä½•時建立環境設定">
+ 設定
+ </text>
+ <check_box name="env_settings_c" value="true"/>
</panel>
<button label="確定" label_selected="確定" name="ok"/>
<button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_pick_track.xml b/indra/newview/skins/default/xui/zh/floater_pick_track.xml
new file mode 100644
index 0000000000..f86132a423
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_pick_track.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="track picker" title="鏿“‡ï¼šè»Œè·¡">
+ <layout_stack name="adjuster">
+ <layout_panel name="pnl_desc">
+ <text name="select_description">
+ 鏿“‡ä¾†æºå¤©ç©ºï¼š
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_traks">
+ <radio_group name="track_selection">
+ <radio_item label="天空4[ALT]" name="radio_sky4" value="4"/>
+ <radio_item label="天空3[ALT]" name="radio_sky3" value="3"/>
+ <radio_item label="天空2[ALT]" name="radio_sky2" value="2"/>
+ <radio_item label="地é¢" name="radio_sky1" value="1"/>
+ </radio_group>
+ </layout_panel>
+ <layout_panel name="pnl_ok_cancel">
+ <button label="確定" label_selected="確定" name="btn_select"/>
+ <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml
index 7b127acd71..58314efeed 100644
--- a/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preferences_graphics_advanced.xml
@@ -82,7 +82,6 @@
<check_box initial_value="true" label="æ¸…æ¾ˆé€æ˜Žçš„æ°´" name="TransparentWater"/>
<check_box initial_value="true" label="凹凸映射與光澤效果" name="BumpShiny"/>
<check_box initial_value="true" label="本地光線" name="LocalLights"/>
- <check_box initial_value="true" label="基本著色" name="BasicShaders" tool_tip="關閉此一é¸é …å¯èƒ½é¿å…部分顯示å¡é©…å‹•ç¨‹å¼ææ¯€ç•¶æ©Ÿ"/>
<slider label="地形細節:" name="TerrainDetail"/>
<text name="TerrainDetailText">
低
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 c56b1c2987..2b6eac48b3 100644
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -10,7 +10,7 @@
æè¿°ï¼š
</text>
<text name="dimensions">
- [WIDTH] åƒç´  X [HEIGHT] åƒç´ 
+ [WIDTH]åƒç´  x [HEIGHT]åƒç´ 
</text>
<text name="aspect_ratio">
é è¦½é•·å¯¬æ¯”
diff --git a/indra/newview/skins/default/xui/zh/floater_settings_picker.xml b/indra/newview/skins/default/xui/zh/floater_settings_picker.xml
new file mode 100644
index 0000000000..36e32777fb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_settings_picker.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="settings picker" title="鏿“‡ï¼šè¨­å®š">
+ <floater.string name="pick title">
+ ç²¾é¸åœ°é»žï¼š
+ </floater.string>
+ <floater.string name="pick_track">
+ é¸å–軌跡
+ </floater.string>
+ <floater.string name="pick_settings">
+ é¸å–設定
+ </floater.string>
+ <floater.string name="track_water">
+ æ°´æ–‡
+ </floater.string>
+ <floater.string name="track_ground">
+ 地é¢
+ </floater.string>
+ <floater.string name="track_sky">
+ 天空[NUM]
+ </floater.string>
+ <layout_stack name="test_stack">
+ <layout_panel name="inv_list">
+ <filter_editor label="æè³ªéŽæ¿¾å™¨" name="flt_inventory_search"/>
+ </layout_panel>
+ <layout_panel name="temp">
+ <button label="確定" label_selected="確定" name="btn_select"/>
+ <button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="btn_cancel"/>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
index 02d06323d4..6fc3e1129b 100644
--- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
@@ -9,17 +9,13 @@
<text name="Multiple">
å¤šé‡æè³ª
</text>
- <radio_group name="mode_selection">
- <radio_item label="æ”¶ç´å€" name="inventory" value="0"/>
- <radio_item label="本地" name="local" value="1"/>
- </radio_group>
- <text name="unknown">
- 尺寸:[DIMENSIONS]
- </text>
+ <combo_box name="mode_selection">
+ <combo_box.item label="æ”¶ç´å€" name="inventory" value="0"/>
+ <combo_box.item label="本地" name="local" value="1"/>
+ </combo_box>
<button label="é è¨­" label_selected="é è¨­" name="Default"/>
<button label="空白" label_selected="空白" name="Blank"/>
<button label="ç„¡" label_selected="ç„¡" name="None"/>
- <check_box initial_value="true" label="ç«‹å³å¥—用" name="apply_immediate_check"/>
<text name="preview_disabled" value="å·²åœç”¨é è¦½"/>
<filter_editor label="æè³ªéŽæ¿¾å™¨" name="inventory search editor"/>
<check_box initial_value="false" label="顯示資料夾" name="show_folders_check"/>
@@ -30,6 +26,22 @@
<column label="å稱" name="unit_name"/>
<column label="ID" name="unit_id_HIDDEN"/>
</scroll_list>
+ <combo_box name="l_bake_use_texture_combo_box" tool_tip="鏿“‡å®šè²Œæè³ª">
+ <combo_box.item label="ç„¡" name="None"/>
+ <combo_box.item label="BAKED_HEAD" name="BAKED_HEAD"/>
+ <combo_box.item label="BAKED_UPPER" name="BAKED_UPPER"/>
+ <combo_box.item label="BAKED_LOWER" name="BAKED_LOWER"/>
+ <combo_box.item label="BAKED_EYES" name="BAKED_EYES"/>
+ <combo_box.item label="BAKED_SKIRT" name="BAKED_SKIRT"/>
+ <combo_box.item label="BAKED_HAIR" name="BAKED_HAIR"/>
+ <combo_box.item label="BAKED_LEFTARM" name="BAKED_LEFTARM"/>
+ <combo_box.item label="BAKED_LEFTLEG" name="BAKED_LEFTLEG"/>
+ <combo_box.item label="BAKED_AUX1" name="BAKED_AUX1"/>
+ <combo_box.item label="BAKED_AUX2" name="BAKED_AUX2"/>
+ <combo_box.item label="BAKED_AUX3" name="BAKED_AUX3"/>
+ </combo_box>
+ <check_box initial_value="false" label="éš±è—基底網é¢å€åŸŸ" name="hide_base_mesh_region"/>
<button label="確定" label_selected="確定" name="Select"/>
<button label="å–æ¶ˆ" label_selected="å–æ¶ˆ" name="Cancel"/>
+ <check_box initial_value="true" label="ç«‹å³å¥—用" name="apply_immediate_check"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
index 876fef16df..6ab2220ca7 100644
--- a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="COF Attachment">
+ <menu_item_call label="觸碰" name="touch_attach" />
+ <menu_item_call label="編輯" name="edit_item" />
<menu_item_call label="å¸ä¸‹" name="detach"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml
index 2ed078841e..10b170d4a4 100644
--- a/indra/newview/skins/default/xui/zh/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml
@@ -10,7 +10,6 @@
<menu_item_call label="啟用" name="Marketplace Activate"/>
<menu_item_call label="åœç”¨" name="Marketplace Deactivate"/>
<menu_item_call label="分享" name="Share"/>
- <menu_item_call label="購買" name="Task Buy"/>
<menu_item_call label="打開" name="Task Open"/>
<menu_item_call label="播放" name="Task Play"/>
<menu_item_call label="屬性" name="Task Properties"/>
@@ -34,6 +33,7 @@
<menu_item_call label="新內褲" name="New Underpants"/>
<menu_item_call label="æ–°åŠé€æ˜Žé®ç½©" name="New Alpha Mask"/>
<menu_item_call label="新刺é’" name="New Tattoo"/>
+ <menu_item_call label="新通用值" name="New Universal"/>
<menu_item_call label="新身體物ç†" name="New Physics"/>
</menu>
<menu label="新身體部ä½" name="New Body Parts">
@@ -42,6 +42,11 @@
<menu_item_call label="æ–°é ­é«®" name="New Hair"/>
<menu_item_call label="新眼ç›" name="New Eyes"/>
</menu>
+ <menu label="新的設定" name="New Settings">
+ <menu_item_call label="新的天空" name="New Sky"/>
+ <menu_item_call label="新的水文" name="New Water"/>
+ <menu_item_call label="新的日循環" name="New Day Cycle"/>
+ </menu>
<menu label="作這一用途的é è¨­å€¼ï¼š" name="upload_def">
<menu_item_call label="圖åƒä¸Šå‚³" name="Image uploads"/>
<menu_item_call label="è²éŸ³ä¸Šå‚³" name="Sound uploads"/>
@@ -100,9 +105,12 @@
<menu_item_call label="穿上" name="Wearable And Object Wear"/>
<menu label="附著到..." name="Attach To"/>
<menu label="附著到擡頭顯示" name="Attach To HUD"/>
+ <menu_item_call label="觸碰" name="Attachment Touch" />
<menu_item_call label="編輯" name="Wearable Edit"/>
<menu_item_call label="添加" name="Wearable Add"/>
<menu_item_call label="脫下" name="Take Off"/>
+ <menu_item_call label="僅套用到我自己" name="Settings Apply Local"/>
+ <menu_item_call label="套用到地段" name="Settings Apply Parcel"/>
<menu_item_call label="複製到 Marketplace 刊登" name="Marketplace Copy"/>
<menu_item_call label="移到 Marketplace 刊登" name="Marketplace Move"/>
<menu_item_call label="-- ç„¡é¸é … --" name="--no options--"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
index 30bf5a7e75..c64b399630 100644
--- a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
@@ -5,9 +5,7 @@
<menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/>
<menu_item_call label="動作(L$[COST])..." name="Upload Animation"/>
<menu_item_call label="模型…" name="Upload Model"/>
- <menu_item_call label="模型精éˆâ€¦" name="Upload Model Wizard"/>
<menu_item_call label="批é‡ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/>
- <menu_item_call label="設定é è¨­ä¸Šå‚³æ¬Šé™" name="perm prefs"/>
</menu>
<menu_item_call label="新資料夾" name="New Folder"/>
<menu_item_call label="新腳本" name="New Script"/>
@@ -25,6 +23,7 @@
<menu_item_call label="新內褲" name="New Underpants"/>
<menu_item_call label="æ–°åŠé€æ˜Ž" name="New Alpha"/>
<menu_item_call label="新刺é’" name="New Tattoo"/>
+ <menu_item_call label="新通用值" name="New Universal"/>
<menu_item_call label="新身體物ç†" name="New Physics"/>
</menu>
<menu label="新身體部ä½" name="New Body Parts">
@@ -33,4 +32,9 @@
<menu_item_call label="æ–°é ­é«®" name="New Hair"/>
<menu_item_call label="新眼ç›" name="New Eyes"/>
</menu>
+ <menu label="新的設定" name="New Settings">
+ <menu_item_call label="新的天空" name="New Sky"/>
+ <menu_item_call label="新的水文" name="New Water"/>
+ <menu_item_call label="新的日循環" name="New Day Cycle"/>
+ </menu>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
index 124598a098..460adf9918 100644
--- a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
@@ -20,6 +20,7 @@
<menu_item_call label="æ–°åŠé€æ˜Ž" name="New Alpha"/>
<menu_item_call label="新身體物ç†" name="New Physics"/>
<menu_item_call label="新刺é’" name="New Tattoo"/>
+ <menu_item_call label="新通用值" name="New Universal"/>
</menu>
<menu label="新身體部ä½" name="New Body Parts">
<menu_item_call label="新體形" name="New Shape"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_save_settings.xml b/indra/newview/skins/default/xui/zh/menu_save_settings.xml
new file mode 100644
index 0000000000..05ec0d97e2
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_save_settings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="save_settings_menu">
+ <menu_item_check label="儲存" name="save_settings"/>
+ <menu_item_check label="å¦å­˜ç‚º" name="save_as_new_settings"/>
+ <menu_item_check label="確定" name="commit_changes"/>
+ <menu_item_check label="僅套用到我自己" name="apply_local"/>
+ <menu_item_check label="套用到地段" name="apply_parcel"/>
+ <menu_item_check label="套用到地å€" name="apply_region"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_settings_add.xml b/indra/newview/skins/default/xui/zh/menu_settings_add.xml
new file mode 100644
index 0000000000..4e11741241
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_settings_add.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_add">
+ <menu_item_call label="新的天空" name="New Sky"/>
+ <menu_item_call label="新的水文" name="New Water"/>
+ <menu_item_call label="新的日循環" name="New Day Cycle"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_settings_gear.xml b/indra/newview/skins/default/xui/zh/menu_settings_gear.xml
new file mode 100644
index 0000000000..342f9d50b4
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_settings_gear.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_settings_gear">
+ <menu_item_call label="編輯" name="edit_settings"/>
+ <menu_item_call label="僅套用到我自己" name="Settings Apply Local"/>
+ <menu_item_call label="套用到地段" name="Settings Apply Parcel"/>
+ <menu_item_call label="套用到地å€" name="Settings Apply Region"/>
+ <menu_item_call label="複製" name="copy_settings"/>
+ <menu_item_call label="貼上" name="paste_settings"/>
+ <menu_item_call label="覆製 UUID" name="copy_uuid"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index a5c9684973..972434dfc5 100644
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -77,30 +77,15 @@
<menu_item_check label="地段屬性" name="Parcel Properties"/>
<menu_item_check label="進階é¸å–®" name="Show Advanced Menu"/>
</menu>
- <menu label="太陽" name="Sun">
+ <menu label="環境" name="Environment">
<menu_item_check label="日出" name="Sunrise"/>
<menu_item_check label="中åˆ" name="Noon"/>
<menu_item_check label="æ—¥è½" name="Sunset"/>
<menu_item_check label="åˆå¤œ" name="Midnight"/>
- <menu_item_check label="使用地å€è¨­å®š" name="Use Region Settings"/>
- </menu>
- <menu label="環境編輯器" name="Environment Editor">
- <menu_item_call label="環境設定…" name="Environment Settings"/>
- <menu label="水的自訂é…ç½®" name="Water Presets">
- <menu_item_call label="新的自訂é…置…" name="new_water_preset"/>
- <menu_item_call label="編輯自訂é…置…" name="edit_water_preset"/>
- <menu_item_call label="刪除自訂é…置…" name="delete_water_preset"/>
- </menu>
- <menu label="天空自訂é…ç½®" name="Sky Presets">
- <menu_item_call label="新的自訂é…置…" name="new_sky_preset"/>
- <menu_item_call label="編輯自訂é…置…" name="edit_sky_preset"/>
- <menu_item_call label="刪除自訂é…置…" name="delete_sky_preset"/>
- </menu>
- <menu label="日的自訂é…ç½®" name="Day Presets">
- <menu_item_call label="新的自訂é…置…" name="new_day_preset"/>
- <menu_item_call label="編輯自訂é…置…" name="edit_day_preset"/>
- <menu_item_call label="刪除自訂é…置…" name="delete_day_preset"/>
- </menu>
+ <menu_item_check label="使用共享環境" name="Use Shared Environment"/>
+ <menu_item_call label="我的環境…" name="my_environs"/>
+ <menu_item_call label="個人照明⋯" name="adjustment_tool"/>
+ <menu_item_check label="æš«åœé›²å½©" name="pause_clouds"/>
</menu>
</menu>
<menu label="建造" name="BuildTools">
@@ -344,6 +329,9 @@
<menu_item_check label="自動åŠé€æ˜Žé®ç½©ï¼ˆéžéžå»¶ï¼‰" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="動作æè³ª" name="Animation Textures"/>
<menu_item_check label="關閉æè³ª" name="Disable Textures"/>
+ <menu_item_check label="åœç”¨ç’°å¢ƒå…‰" name="Disable Ambient"/>
+ <menu_item_check label="åœç”¨æ—¥å…‰" name="Disable Sunlight"/>
+ <menu_item_check label="åœç”¨æœ¬åœ°å…‰ç·š" name="Disable Local Lights"/>
<menu_item_check label="全解æžåº¦æè³ª" name="Rull Res Textures"/>
<menu_item_check label="使附著燈光呈åƒ" name="Render Attached Lights"/>
<menu_item_check label="ä½¿é™„è‘—ä¾‹å­æ•ˆæžœå‘ˆåƒ" name="Render Attached Particles"/>
@@ -481,6 +469,7 @@
<menu_item_call label="裙å­" name="Skirt"/>
<menu_item_call label="åŠé€æ˜Ž" name="Alpha"/>
<menu_item_call label="刺é’" name="Tattoo"/>
+ <menu_item_call label="通用值" name="Universal"/>
<menu_item_call label="身體物ç†" name="Physics"/>
<menu_item_call label="全部衣æœ" name="All Clothes"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
index 576f7f3b73..0093eb68f1 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
<menu_item_call label="å–代" name="wear_replace"/>
<menu_item_call label="穿上" name="wear_wear"/>
<menu_item_call label="添加" name="wear_add"/>
+ <menu_item_call label="觸碰" name="touch" />
<menu_item_call label="è„«ä¸‹è£æ‰® / å¸é™¤é™„ä»¶" name="take_off_or_detach"/>
<menu_item_call label="å¸ä¸‹" name="detach"/>
<context_menu label="附著到..." name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
index 6184f956d1..f09d4cfba9 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear Wearing">
- <menu_item_call label="ç·¨è¼¯è£æ‰®" name="edit"/>
+ <menu_item_call label="觸碰" name="touch"/>
+ <menu_item_call label="編輯" name="edit_item"/>
+ <menu_item_call label="ç·¨è¼¯è£æ‰®" name="edit_outfit"/>
<menu_item_call label="脫下" name="takeoff"/>
<menu_item_call label="è¤‡è£½è£æ‰®æ¸…單到剪貼簿" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
index dc9adcbd25..945297885e 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Wearing">
+ <menu_item_call label="觸碰" name="touch_attach"/>
<menu_item_call label="脫下" name="take_off"/>
<menu_item_call label="å¸ä¸‹" name="detach"/>
- <menu_item_call label="ç·¨è¼¯è£æ‰®" name="edit"/>
+ <menu_item_call label="ç·¨è¼¯è£æ‰®" name="edit_outfit"/>
<menu_item_call label="編輯" name="edit_item"/>
<menu_item_call label="顯示原件" name="show_original"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index d304e95b09..cfde824349 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -1954,6 +1954,11 @@ SHA1 指紋:[MD5_DIGEST]
è‹¥ä¸å‹¾é¸é€™é¸é …,å¯èƒ½æœƒç§»é™¤åœ°æ®µæ‰€æœ‰äººç‚ºé˜²æ­¢æƒ¡æ„騷擾åŠç‚ºç¶­è­·éš±ç§ã€ä¿è­·å¹¼æœªæˆå¹´å±…æ°‘ä¸æŽ¥è§¸æˆå¹´é™åˆ¶ç´šå…§å®¹çš„é™åˆ¶æŽªæ–½ã€‚ 若有必è¦è«‹èˆ‡åœ°æ®µæ‰€æœ‰äººæºé€šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
+ <notification name="EstateParcelEnvironmentOverride">
+ å–æ¶ˆå‹¾é¸é€™é¸é …æœƒç§»é™¤åœ°æ®µæ“æœ‰äººå¢žè¨­æ–¼åœ°æ®µçš„任何自訂環境設定。 若有必è¦è«‹èˆ‡åœ°æ®µæ‰€æœ‰äººæºé€šã€‚
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/>
+ </notification>
<notification name="RegionEntryAccessBlocked">
你所欲å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
<usetemplate name="okbutton" yestext="確定"/>
@@ -2433,7 +2438,15 @@ SHA1 指紋:[MD5_DIGEST]
é€™å€‹ã€Œä¸€æ—¥å¾ªç’°ã€æª”案åƒè€ƒäº†ä¸€å€‹ä¸å­˜åœ¨çš„天空檔案:[SKY]。
</notification>
<notification name="WLRegionApplyFail">
- 抱歉,設定無法套用到地å€ã€‚ 離開地å€å†è¿”回也許å¯ä»¥è§£æ±ºé€™å€‹å•題。 所得的原因為:[FAIL_REASON]
+ 抱歉,設定無法套用到地å€ã€‚ 原因:[FAIL_REASON]
+ </notification>
+ <notification name="WLLocalTextureDayBlock">
+ 一個本地æè³ªæ­£åœ¨ä½¿ç”¨ä¸­ï¼šè»Œè·¡[TRACK],幀#[FRAMENO]([FRAME]%),欄ä½[FIELD]。
+無法儲存使用本地æè³ªçš„設定。
+ </notification>
+ <notification name="WLLocalTextureFixedBlock">
+ 一個本地æè³ªæ­£åœ¨æ¬„ä½[FIELD]使用中。
+無法儲存使用本地æè³ªçš„設定。
</notification>
<notification name="EnvCannotDeleteLastDayCycleKey">
無法刪除此日循環的最後一組設定,日循環ä¸å¾—為空白。 你應該修改最後一組資料,ä¸è¦è©¦åœ–刪除,然後å†å»ºç«‹æ–°çš„。
@@ -4380,4 +4393,76 @@ SHA1 指紋:[MD5_DIGEST]
[REASON]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
+ <notification name="FailedToFindSettings">
+ 無法從資料庫載入[NAME]的設定。
+ </notification>
+ <notification name="FailedToLoadSettingsApply">
+ 無法將設定套用到環境。
+ </notification>
+ <notification name="FailedToBuildSettingsDay">
+ 無法將設定套用到環境。
+ </notification>
+ <notification name="NoEnvironmentSettings">
+ 這å€åŸŸä¸æ”¯æ´ç’°å¢ƒè¨­å®šã€‚
+ </notification>
+ <notification label="å„²å­˜è£æ‰®" name="SaveSettingAs">
+ 把目å‰çš„環境設定儲存為:
+ <form name="form">
+ <input name="message">
+ [DESC](新)
+ </input>
+ <button name="OK" text="確定"/>
+ <button name="Cancel" text="å–æ¶ˆ"/>
+ </form>
+ </notification>
+ <notification name="WLImportFail">
+ 無法匯入舊的風光(Windlight)設定[NAME],來æºï¼š
+[FILE]。
+
+[REASONS]
+ </notification>
+ <notification name="WLParcelApplyFail">
+ 無法設定此地段的環境。
+è«‹è¼¸å…¥æˆ–é¸æ“‡ä¸€å€‹ä½ æœ‰æ¬Šä¿®æ”¹çš„地段。
+ </notification>
+ <notification name="SettingsUnsuported">
+ 這地å€ä¸æ”¯æ´è¨­å®šã€‚
+è«‹ç§»ä½åˆ°æ”¯æ´è¨­å®šçš„地å€ï¼Œå†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="SettingsConfirmLoss">
+ ä½ å³å°‡é‡å°å爲&quot;[NAME]&quot;çš„[TYPE]放棄變更。
+確定繼續?
+ <usetemplate ignoretext="確定放棄變更?" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/>
+ </notification>
+ <notification name="SettingsConfirmReset">
+ ä½ å³å°‡ç§»é™¤æ‰€æœ‰å·²ç”¨çš„設定。
+確定繼續?
+ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/>
+ </notification>
+ <notification name="PersonalSettingsConfirmReset">
+ ä½ å³å°‡ç§»é™¤æ‰€æœ‰å·²ç”¨çš„個人照明設定。
+確定繼續?
+ <usetemplate name="okcancelbuttons" notext="å–æ¶ˆ" yestext="確定"/>
+ </notification>
+ <notification name="SettingsMakeNoTrans">
+ ä½ å³å°‡æŠŠç„¡æ³•轉移的設定匯入這個日循環。 如果繼續,將使得你正在編輯的設定也變æˆç„¡æ³•轉移。
+
+é€™å€‹æ”¹è®Šç„¡æ³•å–æ¶ˆå¾©åŽŸã€‚
+
+確定繼續?
+ <usetemplate ignoretext="ç¢ºå®šè¦æŠŠè¨­å®šè®Šæˆç„¡æ³•轉移?" name="okcancelignore" notext="å–æ¶ˆ" yestext="確定"/>
+ </notification>
+ <notification name="NoEditFromLibrary">
+ ä½ ä¸å¾—直接從資æºåº«ç·¨è¼¯è¨­å®šã€‚
+請複製到你自己的收ç´å€ï¼Œç„¶å¾Œå†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="EnvironmentApplyFailed">
+ 這些設定發生一個å•題。 它們此時無法儲存或套用。
+ </notification>
+ <notification name="TrackLoadFailed">
+ 無法把軌跡載入[TRACK]。
+ </notification>
+ <notification name="TrackLoadMismatch">
+ 無法把軌跡從[TRACK1]載入[TRACK2]。
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
index f5111d629a..10ed653472 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
- <panel name="avatar_tattoo_color_panel">
- <texture_picker label="頭部刺é’" name="Head Tattoo" tool_tip="點按以挑é¸åœ–片"/>
- <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點按以挑é¸åœ–片"/>
- <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點按以挑é¸åœ–片"/>
- <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
- </panel>
+ <scroll_container name="avatar_tattoo_scroll">
+ <panel name="avatar_tattoo_color_panel">
+ <texture_picker label="頭部刺é’" name="Head Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ </panel>
+ </scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_universal.xml b/indra/newview/skins/default/xui/zh/panel_edit_universal.xml
new file mode 100644
index 0000000000..6974efcc89
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_edit_universal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="edit_universal_panel">
+ <scroll_container name="avatar_universal_scroll">
+ <panel name="avatar_universal_color_panel">
+ <texture_picker label="頭部刺é’" name="Head Universal Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="上åŠèº«åˆºé’" name="Upper Universal Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="下åŠèº«åˆºé’" name="Lower Universal Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="裙å­åˆºé’" name="Skirt Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="頭髮刺é’" name="Hair Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="眼ç›åˆºé’" name="Eyes Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="左臂刺é’" name="Left Arm Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="左腿刺é’" name="Left Leg Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="Aux1刺é’" name="Aux1 Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="Aux2刺é’" name="Aux2 Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="Aux3刺é’" name="Aux3 Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ </panel>
+ </scroll_container>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
index 4dd7ea6d93..d41785858a 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
@@ -45,6 +45,9 @@
<string name="edit_tattoo_title">
刺é’編輯中
</string>
+ <string name="edit_universal_title">
+ 編輯通用值
+ </string>
<string name="edit_physics_title">
身體物ç†ç·¨è¼¯ä¸­
</string>
@@ -93,6 +96,9 @@
<string name="tattoo_desc_text">
刺é’:
</string>
+ <string name="universal_desc_text">
+ 通用值:
+ </string>
<string name="physics_desc_text">
身體物ç†ï¼š
</string>
diff --git a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
deleted file mode 100644
index 8de0bb0e4d..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="將物項拖曳並置放到這裡,準備在你的商店出售"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_environment.xml b/indra/newview/skins/default/xui/zh/panel_region_environment.xml
index afea391dda..8caadf50ae 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_environment.xml
@@ -1,33 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="環境" name="panel_env_info">
- <text name="water_settings_title">
- 鏿“‡ä½ å¸Œæœ›åˆ°ä½ åœ°å€çš„訪客所能看到的水和天空 / 日循環設定。 詳情
- </text>
- <radio_group name="region_settings_radio_group">
- <radio_item label="使用第二人生é è¨­å€¼" name="use_sl_default_settings"/>
- <radio_item label="使用以下設定" name="use_my_settings"/>
- </radio_group>
- <panel name="user_environment_settings">
- <text name="water_settings_title">
- 水的設定
- </text>
- <combo_box name="water_settings_preset_combo">
- <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
- </combo_box>
- <text name="sky_dayc_settings_title">
- å¤©ç©ºï¼æ—¥å¾ªç’°
- </text>
- <radio_group name="sky_dayc_settings_radio_group">
- <radio_item label="固定天空" name="my_sky_settings"/>
- <radio_item label="日循環" name="my_dayc_settings"/>
- </radio_group>
- <combo_box name="sky_settings_preset_combo">
- <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
- </combo_box>
- <combo_box name="dayc_settings_preset_combo">
- <combo_box.item label="-鏿“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
- </combo_box>
- </panel>
- <button label="套用" name="apply_btn"/>
- <button label="å–æ¶ˆ" name="cancel_btn"/>
+ <string name="str_label_use_default">
+ 使用é è¨­è¨­å®š
+ </string>
+ <string name="str_label_use_region">
+ 使用地å€è¨­å®š
+ </string>
+ <string name="str_altitude_desription">
+ 天空 [INDEX]([ALTITUDE]m)
+ </string>
+ <string name="str_no_parcel">
+ æœªé¸æ“‡åœ°æ®µã€‚ 環境設定已åœç”¨ã€‚
+ </string>
+ <string name="str_cross_region">
+ 跨越地å€ä¸æä¾›ç’°å¢ƒè¨­å®šã€‚
+ </string>
+ <string name="str_legacy">
+ 這地å€ä¸æä¾›ç’°å¢ƒè¨­å®šã€‚
+ </string>
+ <string name="str_disallowed">
+ 領地管ç†äººä¸å…許改變此å€åŸŸçš„地段環境。
+ </string>
+ <string name="str_too_small">
+ 地段必須至少128平方公尺æ‰å¯æ”¯æ’環境。
+ </string>
+ <string name="str_empty">
+ (空白)
+ </string>
+ <string name="str_region_env">
+ (地å€ç’°å¢ƒï¼‰
+ </string>
+ <layout_stack>
+ <layout_panel name="pnl_environment_disabled">
+ <text name="txt_environment_disabled">
+ ...
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_config">
+ <layout_stack>
+ <layout_panel name="pnl_environment_current">
+ <button label="[USEDEFAULT]" name="btn_usedefault"/>
+ <button label="使用收ç´å€" name="btn_select_inventory"/>
+ <button label="自訂" name="btn_edit"/>
+ <check_box label="地段所有人å¯å¼·åˆ¶è¨­å®šç’°å¢ƒ" name="chk_allow_override"/>
+ </layout_panel>
+ <layout_panel name="pnl_environment_length">
+ <text name="lbl_apparent_time">
+ [HH]:[MM][AP] ([PRC]%)
+ </text>
+ </layout_panel>
+ <layout_panel name="pnl_environment_buttons"/>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="pnl_environment_altitudes">
+ <panel name="pnl_alt1">
+ <text name="txt_alt1">
+ 天空[INDEX]
+ [ALTITUDE]公尺
+ </text>
+ <line_editor name="edt_invname_alt1">
+ 未知
+ </line_editor>
+ <settings_drop_target name="sdt_alt1" tool_tip="將一個設定從收ç´å€æ‹–æ›³åˆ°é€™å€‹ç›®æ¨™ç®±æ¡†ï¼Œä¾¿å¯æŠŠå®ƒé¸å®šç‚ºç›®å‰çš„天空。"/>
+ </panel>
+ <panel name="pnl_alt2">
+ <text name="txt_alt2">
+ 天空[INDEX]
+ [ALTITUDE]公尺
+ </text>
+ <line_editor name="edt_invname_alt2">
+ 未知
+ </line_editor>
+ <settings_drop_target name="sdt_alt2" tool_tip="將一個設定從收ç´å€æ‹–æ›³åˆ°é€™å€‹ç›®æ¨™ç®±æ¡†ï¼Œä¾¿å¯æŠŠå®ƒé¸å®šç‚ºç›®å‰çš„天空。"/>
+ </panel>
+ <panel name="pnl_alt3">
+ <text name="txt_alt3">
+ 天空[INDEX]
+ [ALTITUDE]公尺
+ </text>
+ <line_editor name="edt_invname_alt3">
+ 未知
+ </line_editor>
+ <settings_drop_target name="sdt_alt3" tool_tip="將一個設定從收ç´å€æ‹–æ›³åˆ°é€™å€‹ç›®æ¨™ç®±æ¡†ï¼Œä¾¿å¯æŠŠå®ƒé¸å®šç‚ºç›®å‰çš„天空。"/>
+ </panel>
+ <multi_slider initial_value="0" name="sld_altitudes">
+ <slider name="sld1" value="1000"/>
+ <slider name="sld2" value="2000"/>
+ <slider name="sld3" value="3000"/>
+ </multi_slider>
+ <panel name="pnl_ground">
+ <text name="txt_ground">
+ 地é¢
+ </text>
+ <line_editor name="edt_invname_ground">
+ 未知
+ </line_editor>
+ <settings_drop_target name="sdt_ground" tool_tip="將一個設定從收ç´å€æ‹–æ›³åˆ°é€™å€‹ç›®æ¨™ç®±æ¡†ï¼Œä¾¿å¯æŠŠå®ƒé¸å®šç‚ºåœ°é¢æ°´å¹³çš„天空。"/>
+ </panel>
+ <panel name="pnl_water">
+ <text name="txt_water">
+ æ°´æ–‡
+ </text>
+ <line_editor name="edt_invname_water">
+ 未知
+ </line_editor>
+ <settings_drop_target name="sdt_water" tool_tip="將一個設定從收ç´å€æ‹–æ›³åˆ°é€™å€‹ç›®æ¨™ç®±æ¡†ï¼Œä¾¿å¯æŠŠå®ƒé¸å®šç‚ºç›®å‰çš„æ°´æ–‡ã€‚"/>
+ </panel>
+ <button label="é‡è¨­" name="btn_rst_altitudes" tool_tip="é‡è¨­ç‚ºé è¨­é«˜åº¦"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/zh/panel_settings_sky_atmos.xml
new file mode 100644
index 0000000000..a352055d6d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_settings_sky_atmos.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="大氣與照明" name="panel_settings_sky_atmos"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/zh/panel_settings_sky_clouds.xml
new file mode 100644
index 0000000000..e27e2278df
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_settings_sky_clouds.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="雲彩" name="panel_settings_sky_clouds">
+ <layout_stack>
+ <layout_panel>
+ <slider label="X" name="cloud_density_x"/>
+ <slider label="Y" name="cloud_density_y"/>
+ <slider label="D" name="cloud_density_d"/>
+ <slider label="X" name="cloud_detail_x"/>
+ <slider label="Y" name="cloud_detail_y"/>
+ <slider label="D" name="cloud_detail_d"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_settings_sky_density.xml b/indra/newview/skins/default/xui/zh/panel_settings_sky_density.xml
new file mode 100644
index 0000000000..ddd5ecfe49
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_settings_sky_density.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="密度" name="panel_settings_sky_density">
+ <layout_stack>
+ <layout_panel>
+ <slider label="Rayleigh指數項:" name="rayleigh_exponential"/>
+ <slider label="Rayleigh指數比例尺:" name="rayleigh_exponential_scale"/>
+ <slider label="Rayleigh線性項:" name="rayleigh_linear"/>
+ <slider label="Rayleigh常數項:" name="rayleigh_constant"/>
+ <slider label="Rayleigh最大高度:" name="rayleigh_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="Mie指數項:" name="mie_exponential"/>
+ <slider label="Mie指數比例尺:" name="mie_exponential_scale"/>
+ <slider label="Mie線性項:" name="mie_linear"/>
+ <slider label="Mie常數項:" name="mie_constant"/>
+ <slider label="Mie Aniso因數:" name="mie_aniso_factor"/>
+ <slider label="Mie最大高度:" name="mie_max_altitude"/>
+ </layout_panel>
+ <layout_panel>
+ <slider label="叿”¶æŒ‡æ•¸é …:" name="absorption_exponential"/>
+ <slider label="叿”¶æŒ‡æ•¸æ¯”例尺:" name="absorption_exponential_scale"/>
+ <slider label="叿”¶ç·šæ€§é …:" name="absorption_linear"/>
+ <slider label="叿”¶å¸¸æ•¸é …:" name="absorption_constant"/>
+ <slider label="叿”¶æœ€å¤§é«˜åº¦ï¼š" name="absorption_max_altitude"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/zh/panel_settings_sky_sunmoon.xml
new file mode 100644
index 0000000000..7d1d433cbc
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_settings_sky_sunmoon.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="日與月" name="panel_settings_sky_hbodies">
+ <layout_stack>
+ <layout_panel name="sun_layout">
+ <check_box label="顯示指標" name="sunbeacon"/>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack>
+ <layout_panel name="moon_layout">
+ <check_box label="顯示指標" name="moonbeacon"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_settings_water.xml b/indra/newview/skins/default/xui/zh/panel_settings_water.xml
new file mode 100644
index 0000000000..59687c001b
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_settings_water.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="æ°´æ–‡" name="panel_settings_water">
+ <layout_stack name="water_stack1">
+ <layout_panel>
+ <text name="FresnelOffsetText">
+ è²æ¶…耳åè·ï¼š
+ </text>
+ </layout_panel>
+ <layout_panel>
+ <layout_stack name="water_stack2">
+ <layout_panel>
+ <slider label="X:" name="water_normal_scale_x"/>
+ <slider label="Y:" name="water_normal_scale_y"/>
+ <slider label="Z:" name="water_normal_scale_z"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_tools_texture.xml b/indra/newview/skins/default/xui/zh/panel_tools_texture.xml
index 9a4e2f68a8..f7868ff855 100644
--- a/indra/newview/skins/default/xui/zh/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/zh/panel_tools_texture.xml
@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="æè³ª" name="Texture">
- <panel.string name="string repeats per meter">
- æ¯å…¬å°ºé‡è¦†æ¬¡æ•¸
- </panel.string>
- <panel.string name="string repeats per face">
- æ¯ä¸€é¢é‡è¦†æ¬¡æ•¸
- </panel.string>
<text name="color label">
é¡è‰²
</text>
@@ -114,4 +108,5 @@
<spinner label="æ°´å¹³åè·" name="shinyOffsetU"/>
<spinner label="垂直åè·" name="shinyOffsetV"/>
<check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="ä»¥æœ€å¾Œæ‰€é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æè³ªã€‚ é€™å¿…é ˆä½¿ç”¨å¹³é¢æè³ªæ˜ å°„æ–¹å¼ã€‚"/>
+ <button label="å°é½Š" label_selected="å°é½Šç›®å‰çš„æè³ªå±¤æ¬¡" name="button align textures" tool_tip="å°é½Šç›®å‰çš„æè³ªå±¤æ¬¡"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/role_actions.xml b/indra/newview/skins/default/xui/zh/role_actions.xml
index e3b0eb1261..e7865b6056 100644
--- a/indra/newview/skins/default/xui/zh/role_actions.xml
+++ b/indra/newview/skins/default/xui/zh/role_actions.xml
@@ -33,6 +33,7 @@
<action description="更改音樂和媒體設定" longdescription="在「土地資料ã€&gt; 媒體é ç±¤æ›´æ”¹ä¸²æµéŸ³æ¨‚和影片設定。" name="land change media" value="20"/>
<action description="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨­å®š" longdescription="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨­å®šã€‚ *警告* 「土地資料ã€&gt; 「é¸é …ã€é ç±¤ &gt;「編輯地形ã€å¯å…許任何人變更你的土地形狀,放置或移動 Linden æ¤ç‰©ã€‚ 賦予這項能力之å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚ 編輯地形å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤åšåˆ‡æ›ã€‚" name="land edit" value="21"/>
<action description="切æ›å„項「土地資料ã€&gt; é¸é …設定" longdescription="在「土地資料ã€&gt; é¸é …é ç±¤åˆ‡æ›ã€Œå®‰å…¨ï¼ˆç„¡å‚·å®³ï¼‰ã€è¨­å®šï¼Œä¸¦å…許其他居民在群組所有土地上「編輯地形ã€ã€ã€Œå»ºè£½ã€ã€ã€Œå»ºç«‹åœ°æ¨™ã€ã€ã€ŒåŸ·è¡Œè…³æœ¬ã€ã€‚" name="land options" value="22"/>
+ <action description="修改環境設定和日循環。" longdescription="從「土地資料ã€&gt;「環境é ç±¤ã€è®Šæ›´ç’°å¢ƒè¨­å®šå’Œæ—¥å¾ªç’°ã€‚" name="land change environment" value="46"/>
</action_set>
<action_set description="這些能力包括å¯å…許æˆå“¡åœ¨ç¾¤çµ„所有地段上è¦é¿é™åˆ¶ã€‚" name="Parcel Powers">
<action description="固定å…許「編輯地形ã€" longdescription="身負具此能力的角色的æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上編輯地形,無論這功能在「土地資料ã€&gt; é¸é …é ç±¤è£¡æ˜¯å¦è¢«ç¦æ­¢ã€‚" name="land allow edit land" value="23"/>
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index bbbaf57501..e6c61a5d94 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -635,6 +635,15 @@ http://secondlife.com/viewer-access-faq
<string name="BUTTON_HELP">
顯示幫助
</string>
+ <string name="TooltipNotecardNotAllowedTypeDrop">
+ 這種類型的物項ä¸èƒ½é™„è‘—
+到這一å€åŸŸçš„記事å¡ã€‚
+ </string>
+ <string name="TooltipNotecardOwnerRestrictedDrop">
+ å”¯æœ‰ã€Œä¸‹ä¸€æ‰€æœ‰äººã€æ¬Šé™
+ä¸å—é™åˆ¶çš„物項æ‰å¯
+附著到記事å¡ã€‚
+ </string>
<string name="Searching">
æœå°‹ä¸­...
</string>
@@ -711,6 +720,18 @@ http://secondlife.com/viewer-access-faq
ä¸Šå‚³è¦æ±‚發生錯誤。 è«‹åƒè¦‹ï¼š
http://secondlife.com/support 求助解決å•題。
</string>
+ <string name="SettingValidationError">
+ 匯入設定[NAME]時驗證失敗
+ </string>
+ <string name="SettingImportFileError">
+ 無法開啟檔案[FILE]
+ </string>
+ <string name="SettingParseFileError">
+ 無法開啟檔案[FILE]
+ </string>
+ <string name="SettingTranslateError">
+ 無法轉譯舊的風光(windlight)[NAME]
+ </string>
<string name="texture">
æè³ª
</string>
@@ -786,6 +807,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="symbolic folder link">
資料夾è¯çµ
</string>
+ <string name="settings blob">
+ 設定
+ </string>
<string name="mesh">
ç¶²é¢
</string>
@@ -1116,6 +1140,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="ForceSitAvatar">
強迫你的化身å下
</string>
+ <string name="ChangeEnvSettings">
+ 改變你的環境設定
+ </string>
<string name="NotConnected">
æœªè¯æŽ¥
</string>
@@ -1267,6 +1294,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="tattoo">
刺é’
</string>
+ <string name="universal">
+ 通用值
+ </string>
<string name="physics">
身體物ç†
</string>
@@ -1309,6 +1339,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="tattoo_not_worn">
åˆºé’æœªç©¿
</string>
+ <string name="universal_not_worn">
+ 未穿戴通用值
+ </string>
<string name="physics_not_worn">
èº«é«”ç‰©ç†æœªç©¿
</string>
@@ -1360,6 +1393,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="create_new_tattoo">
創造新刺é’
</string>
+ <string name="create_new_universal">
+ 創立新的通用值
+ </string>
<string name="create_new_physics">
創造新身體物ç†
</string>
@@ -2507,6 +2543,27 @@ http://secondlife.com/support 求助解決å•題。
<string name="RegionSettings">
地å€è¨­å®š
</string>
+ <string name="NoEnvironmentSettings">
+ 這å€åŸŸä¸æ”¯æ´ç’°å¢ƒè¨­å®šã€‚
+ </string>
+ <string name="EnvironmentSun">
+ 太陽
+ </string>
+ <string name="EnvironmentMoon">
+ 月亮
+ </string>
+ <string name="EnvironmentBloom">
+ 開花
+ </string>
+ <string name="EnvironmentCloudNoise">
+ 雲彩噪度
+ </string>
+ <string name="EnvironmentNormalMap">
+ 正常地圖
+ </string>
+ <string name="EnvironmentTransparent">
+ 逿˜Ž
+ </string>
<string name="ClassifiedClicksTxt">
點按:[TELEPORT] 瞬間傳é€ï¼Œ[MAP] 地圖,[PROFILE] 檔案
</string>
@@ -4723,6 +4780,9 @@ http://secondlife.com/support 求助解決å•題。
<string name="New Tattoo">
新刺é’
</string>
+ <string name="New Universal">
+ 新通用值
+ </string>
<string name="New Physics">
新身體物ç†
</string>
@@ -4849,6 +4909,15 @@ http://secondlife.com/support 求助解決å•題。
<string name="Female - Wow">
女性 - 哇塞
</string>
+ <string name="New Daycycle">
+ 新的日循環
+ </string>
+ <string name="New Water">
+ 新的水文
+ </string>
+ <string name="New Sky">
+ 新的天空
+ </string>
<string name="/bow">
/彎腰點頭
</string>
@@ -5389,6 +5458,12 @@ http://secondlife.com/support 求助解決å•題。
<string name="BeaconMedia">
檢視媒體的導引(白色)
</string>
+ <string name="BeaconSun">
+ æª¢è¦–å¤ªé™½æ–¹å‘æŒ‡æ¨™ï¼ˆæ©˜è‰²ï¼‰
+ </string>
+ <string name="BeaconMoon">
+ æª¢è¦–æœˆäº®æ–¹å‘æŒ‡æ¨™ï¼ˆç´«è‰²ï¼‰
+ </string>
<string name="ParticleHiding">
éš±è—ç²’å­æ•ˆæžœ
</string>
@@ -5416,6 +5491,12 @@ http://secondlife.com/support 求助解決å•題。
<string name="Command_Destinations_Label">
目的地
</string>
+ <string name="Command_Environments_Label">
+ 我的環境
+ </string>
+ <string name="Command_Facebook_Label">
+ 臉書
+ </string>
<string name="Command_Flickr_Label">
Flickr
</string>
@@ -5509,6 +5590,12 @@ http://secondlife.com/support 求助解決å•題。
<string name="Command_Destinations_Tooltip">
ä½ å¯èƒ½æ„Ÿèˆˆè¶£çš„目的地
</string>
+ <string name="Command_Environments_Tooltip">
+ 我的環境
+ </string>
+ <string name="Command_Facebook_Tooltip">
+ 發佈到臉書
+ </string>
<string name="Command_Flickr_Tooltip">
上傳到 Flickr
</string>
@@ -5704,6 +5791,12 @@ http://secondlife.com/support 求助解決å•題。
<string name="ExperiencePermission12">
自動接å—å„種體驗權é™
</string>
+ <string name="ExperiencePermission16">
+ 強迫你的化身å下
+ </string>
+ <string name="ExperiencePermission17">
+ 改變你的環境設定
+ </string>
<string name="ExperiencePermissionShortUnknown">
進行了未知的æ“作:[Permission]
</string>
@@ -5728,6 +5821,12 @@ http://secondlife.com/support 求助解決å•題。
<string name="ExperiencePermissionShort12">
權é™
</string>
+ <string name="ExperiencePermissionShort16">
+ å下
+ </string>
+ <string name="ExperiencePermissionShort17">
+ 環境
+ </string>
<string name="logging_calls_disabled_log_empty">
交談未留記錄。 若想開始留記錄,請到「å好設定 &gt; èŠå¤©ã€ï¼Œé¸æ“‡ã€Œå„²å­˜ï¼šåªç•™æ­·å²è¨˜éŒ„ã€æˆ–「儲存:歷å²è¨˜éŒ„兼交談內容ã€ã€‚
</string>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 2edad30493..f9abc8b25d 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -41,6 +41,7 @@
#include "../test/lltut.h"
#include "llevents.h"
#include "llnotificationsutil.h"
+#include "lltrans.h"
#if defined(LL_WINDOWS)
#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr
@@ -77,6 +78,11 @@ void LLViewerWindow::setShowProgress(BOOL show) {}
LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
LLViewerWindow* gViewerWindow;
+
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
+{
+ return std::string("test_trans");
+}
class LLLogin::Impl
{
@@ -202,8 +208,6 @@ void LLUIColorTable::saveUserSettings(void)const {}
//-----------------------------------------------------------------------------
#include "../llversioninfo.h"
-const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }
-const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
bool llHashedUniqueID(unsigned char* id)
{
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index d7e87ed52e..caa3016d2e 100644
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -60,12 +60,22 @@ LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert
LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; }
LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; }
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
+void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
+void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; }
void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {}
+bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid) { return false; }
+bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid) { return false; }
+void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map) {}
+LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) { return NULL; }
+void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator) {}
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred) {}
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) {}
+void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid) {}
// -------------------------------------------------------------------------------------------
// TUT
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 63967fae37..e5d226a2a4 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -124,6 +124,14 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
S32 LLMachineID::init() { return 1; }
+LLCertException::LLCertException(const LLSD& cert_data, const std::string& msg)
+ : LLException(msg),
+ mCertData(cert_data)
+{
+ LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;
+}
+
+
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 58f0469552..51a6f8f113 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -83,39 +83,39 @@ namespace tut
void versioninfo_object_t::test<1>()
{
std::cout << "What we parsed from CMake: " << LL_VIEWER_VERSION_BUILD << std::endl;
- std::cout << "What we get from llversioninfo: " << LLVersionInfo::getBuild() << std::endl;
+ std::cout << "What we get from llversioninfo: " << LLVersionInfo::instance().getBuild() << std::endl;
ensure_equals("Major version",
- LLVersionInfo::getMajor(),
+ LLVersionInfo::instance().getMajor(),
LL_VIEWER_VERSION_MAJOR);
ensure_equals("Minor version",
- LLVersionInfo::getMinor(),
+ LLVersionInfo::instance().getMinor(),
LL_VIEWER_VERSION_MINOR);
ensure_equals("Patch version",
- LLVersionInfo::getPatch(),
+ LLVersionInfo::instance().getPatch(),
LL_VIEWER_VERSION_PATCH);
ensure_equals("Build version",
- LLVersionInfo::getBuild(),
+ LLVersionInfo::instance().getBuild(),
LL_VIEWER_VERSION_BUILD);
ensure_equals("Channel version",
- LLVersionInfo::getChannel(),
+ LLVersionInfo::instance().getChannel(),
ll_viewer_channel);
ensure_equals("Version String",
- LLVersionInfo::getVersion(),
+ LLVersionInfo::instance().getVersion(),
mVersion);
ensure_equals("Short Version String",
- LLVersionInfo::getShortVersion(),
+ LLVersionInfo::instance().getShortVersion(),
mShortVersion);
ensure_equals("Version and channel String",
- LLVersionInfo::getChannelAndVersion(),
+ LLVersionInfo::instance().getChannelAndVersion(),
mVersionAndChannel);
- LLVersionInfo::resetChannel(mResetChannel);
+ LLVersionInfo::instance().resetChannel(mResetChannel);
ensure_equals("Reset channel version",
- LLVersionInfo::getChannel(),
+ LLVersionInfo::instance().getChannel(),
mResetChannel);
ensure_equals("Reset Version and channel String",
- LLVersionInfo::getChannelAndVersion(),
+ LLVersionInfo::instance().getChannelAndVersion(),
mResetVersionAndChannel);
}
}
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index bb28abead3..fe81fd63ea 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -258,7 +258,7 @@ namespace tut
std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Aditi helper uri",
LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
- std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
+ std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
@@ -330,7 +330,7 @@ namespace tut
std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
ensure_equals("Aditi helper uri",
LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
- std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
+ std::string("https://secondlife.aditi.lindenlab.com/helpers/"));
ensure_equals("Aditi login page",
LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
std::string("https://viewer-splash.secondlife.com/"));
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index a403760670..adac7af712 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -78,6 +78,9 @@ class ViewerManifest(LLManifest):
contributor_names = self.extract_names(contributions_path)
self.put_in_file(contributor_names, "contributors.txt", src=contributions_path)
+ # ... and the default camera position settings
+ self.path("camera")
+
# ... and the entire windlight directory
self.path("windlight")
@@ -257,6 +260,9 @@ class ViewerManifest(LLManifest):
app_suffix=self.channel_variant()
return CHANNEL_VENDOR_BASE + ' ' + app_suffix
+ def exec_name(self):
+ return "SecondLifeViewer"
+
def app_name_oneword(self):
return ''.join(self.app_name().split())
@@ -416,10 +422,9 @@ class WindowsManifest(ViewerManifest):
build_data_json_platform = 'win'
def final_exe(self):
- return self.app_name_oneword()+".exe"
+ return self.exec_name()+".exe"
def finish_build_data_dict(self, build_data_dict):
- #MAINT-7294: Windows exe names depend on channel name, so write that in also
build_data_dict['Executable'] = self.final_exe()
build_data_dict['AppName'] = self.app_name()
return build_data_dict
@@ -513,26 +518,28 @@ class WindowsManifest(ViewerManifest):
print err.message
print "Skipping GLOD library (assumming linked statically)"
- # Get fmodex dll, continue if missing
- try:
- if(self.address_size == 64):
- self.path("fmodex64.dll")
+ # Get fmodstudio dll if needed
+ if self.args['fmodstudio'] == 'ON':
+ if(self.args['configuration'].lower() == 'debug'):
+ self.path("fmodL.dll")
else:
- self.path("fmodex.dll")
- except:
- print "Skipping fmodex audio library(assuming other audio engine)"
+ self.path("fmod.dll")
+
+ if self.args['openal'] == 'ON':
+ # Get openal dll
+ self.path("OpenAL32.dll")
+ self.path("alut.dll")
# For textures
self.path("openjpeg.dll")
+ # Uriparser
+ self.path("uriparser.dll")
+
# These need to be installed as a SxS assembly, currently a 'private' assembly.
# See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
- if self.args['configuration'].lower() == 'debug':
- self.path("msvcr120d.dll")
- self.path("msvcp120d.dll")
- else:
- self.path("msvcr120.dll")
- self.path("msvcp120.dll")
+ self.path("msvcp140.dll")
+ self.path("vcruntime140.dll")
# SLVoice executable
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
@@ -593,21 +600,19 @@ class WindowsManifest(ViewerManifest):
config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
self.path("chrome_elf.dll")
- self.path("d3dcompiler_43.dll")
self.path("d3dcompiler_47.dll")
self.path("libcef.dll")
self.path("libEGL.dll")
self.path("libGLESv2.dll")
self.path("dullahan_host.exe")
- self.path("natives_blob.bin")
self.path("snapshot_blob.bin")
self.path("v8_context_snapshot.bin")
# MSVC DLLs needed for CEF and have to be in same directory as plugin
with self.prefix(src=os.path.join(self.args['build'], os.pardir,
'sharedlibs', 'Release')):
- self.path("msvcp120.dll")
- self.path("msvcr120.dll")
+ self.path("msvcp140.dll")
+ self.path("vcruntime140.dll")
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources')):
@@ -794,6 +799,7 @@ class WindowsManifest(ViewerManifest):
for exe in (
self.final_exe(),
"SLVersionChecker.exe",
+ "llplugin/dullahan_host.exe",
):
self.sign(exe)
@@ -827,13 +833,13 @@ class WindowsManifest(ViewerManifest):
def sign(self, exe):
sign_py = os.environ.get('SIGN', r'C:\buildscripts\code-signing\sign.py')
- python = os.environ.get('PYTHON', 'python')
+ python = os.environ.get('PYTHON', sys.executable)
if os.path.exists(sign_py):
dst_path = self.dst_path_of(exe)
print "about to run signing of: ", dst_path
self.run_command([python, sign_py, dst_path])
else:
- print "Skipping code signing of %s: %s not found" % (exe, sign_py)
+ print "Skipping code signing of %s %s: %s not found" % (self.dst_path_of(exe), exe, sign_py)
def escape_slashes(self, path):
return path.replace('\\', '\\\\\\\\')
@@ -956,7 +962,7 @@ class DarwinManifest(ViewerManifest):
with self.prefix(src=relpkgdir, dst=""):
self.path("libndofdev.dylib")
- self.path("libhunspell-1.3.a")
+ self.path("libhunspell-*.dylib")
with self.prefix(src_dst="cursors_mac"):
self.path("*.tif")
@@ -1032,6 +1038,7 @@ class DarwinManifest(ViewerManifest):
# libnghttp2.major.dylib, which is a symlink to
# libnghttp2.version.dylib. Get all of them.
"libnghttp2.*dylib",
+ "liburiparser.*dylib",
):
dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
@@ -1046,17 +1053,18 @@ class DarwinManifest(ViewerManifest):
):
self.path2basename(relpkgdir, libfile)
- # dylibs that vary based on configuration
- if self.args['configuration'].lower() == 'debug':
- for libfile in (
- "libfmodexL.dylib",
- ):
- dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
- else:
- for libfile in (
- "libfmodex.dylib",
- ):
- dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
+ # Fmod studio dylibs (vary based on configuration)
+ if self.args['fmodstudio'] == 'ON':
+ if self.args['configuration'].lower() == 'debug':
+ for libfile in (
+ "libfmodL.dylib",
+ ):
+ dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
+ else:
+ for libfile in (
+ "libfmod.dylib",
+ ):
+ dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
# our apps
executable_path = {}
@@ -1103,46 +1111,55 @@ class DarwinManifest(ViewerManifest):
# $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
- # copy DullahanHelper.app
- self.path2basename(relpkgdir, 'DullahanHelper.app')
-
- # and fix that up with a Frameworks/CEF symlink too
- with self.prefix(dst=os.path.join(
- 'DullahanHelper.app', 'Contents', 'Frameworks')):
- # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
- # Framework.framework back to
- # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
- # Since SLPlugin_framework is itself a
- # symlink, don't let relsymlinkf() resolve --
- # explicitly call relpath(symlink=True) and
- # create that symlink here.
- DullahanHelper_framework = \
- self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
- catch=False)
-
- # change_command includes install_name_tool, the
- # -change subcommand and the old framework rpath
- # stamped into the executable. To use it with
- # run_command(), we must still append the new
- # framework path and the pathname of the
- # executable to change.
- change_command = [
- 'install_name_tool', '-change',
- '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
-
- with self.prefix(dst=os.path.join(
- 'DullahanHelper.app', 'Contents', 'MacOS')):
- # Now self.get_dst_prefix() is, at runtime,
- # @executable_path. Locate the helper app
- # framework (which is a symlink) from here.
- newpath = os.path.join(
- '@executable_path',
- self.relpath(DullahanHelper_framework, symlink=True),
- frameworkname)
- # and restamp the DullahanHelper executable
- self.run_command(
- change_command +
- [newpath, self.dst_path_of('DullahanHelper')])
+ # for all the multiple CEF/Dullahan (as of CEF 76) helper app bundles we need:
+ for helper in (
+ "DullahanHelper",
+ "DullahanHelper (GPU)",
+ "DullahanHelper (Renderer)",
+ "DullahanHelper (Plugin)",
+ ):
+ # app is the directory name of the app bundle, with app/Contents/MacOS/helper as the executable
+ app = helper + ".app"
+
+ # copy DullahanHelper.app
+ self.path2basename(relpkgdir, app)
+
+ # and fix that up with a Frameworks/CEF symlink too
+ with self.prefix(dst=os.path.join(
+ app, 'Contents', 'Frameworks')):
+ # from Dullahan Helper *.app/Contents/Frameworks/Chromium Embedded
+ # Framework.framework back to
+ # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
+ # Since SLPlugin_framework is itself a
+ # symlink, don't let relsymlinkf() resolve --
+ # explicitly call relpath(symlink=True) and
+ # create that symlink here.
+ helper_framework = \
+ self.symlinkf(self.relpath(SLPlugin_framework, symlink=True), catch=False)
+
+ # change_command includes install_name_tool, the
+ # -change subcommand and the old framework rpath
+ # stamped into the executable. To use it with
+ # run_command(), we must still append the new
+ # framework path and the pathname of the
+ # executable to change.
+ change_command = [
+ 'install_name_tool', '-change',
+ '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
+
+ with self.prefix(dst=os.path.join(
+ app, 'Contents', 'MacOS')):
+ # Now self.get_dst_prefix() is, at runtime,
+ # @executable_path. Locate the helper app
+ # framework (which is a symlink) from here.
+ newpath = os.path.join(
+ '@executable_path',
+ self.relpath(helper_framework, symlink=True),
+ frameworkname)
+ # and restamp the Dullahan Helper executable itself
+ self.run_command(
+ change_command +
+ [newpath, self.dst_path_of(helper)])
# SLPlugin plugins
with self.prefix(dst="llplugin"):
@@ -1205,11 +1222,6 @@ class DarwinManifest(ViewerManifest):
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
- if devfile != '/dev/disk1':
- # adding more debugging info based upon nat's hunches to the
- # logs to help track down 'SetFile -a V' failures -brad
- print "WARNING: 'SetFile -a V' command below is probably gonna fail"
-
# Copy everything in to the mounted .dmg
app_name = self.app_name()
@@ -1237,21 +1249,6 @@ class DarwinManifest(ViewerManifest):
# Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
for f in ".VolumeIcon.icns", "background.jpg", ".DS_Store":
pathname = os.path.join(volpath, f)
- # We've observed mysterious "no such file" failures of the SetFile
- # command, especially on the first file listed above -- yet
- # subsequent inspection of the target directory confirms it's
- # there. Timing problem with copy command? Try to handle.
- for x in xrange(3):
- if os.path.exists(pathname):
- print "Confirmed existence: %r" % pathname
- break
- print "Waiting for %s copy command to complete (%s)..." % (f, x+1)
- sys.stdout.flush()
- time.sleep(1)
- # If we fall out of the loop above without a successful break, oh
- # well, possibly we've mistaken the nature of the problem. In any
- # case, don't hang up the whole build looping indefinitely, let
- # the original problem manifest by executing the desired command.
self.run_command(['SetFile', '-a', 'V', pathname])
# Create the alias file (which is a resource file) from the .r
@@ -1519,14 +1516,15 @@ class Linux_i686_Manifest(LinuxManifest):
print "tcmalloc files not found, skipping"
pass
- try:
- self.path("libfmodex-*.so")
- self.path("libfmodex.so")
- pass
- except:
- print "Skipping libfmodex.so - not found"
- pass
-
+ if self.args['fmodstudio'] == 'ON':
+ try:
+ self.path("libfmod.so.11.7")
+ self.path("libfmod.so.11")
+ self.path("libfmod.so")
+ pass
+ except:
+ print "Skipping libfmod.so - not found"
+ pass
# Vivox runtimes
with self.prefix(src=relpkgdir, dst="bin"):
@@ -1552,9 +1550,17 @@ class Linux_x86_64_Manifest(LinuxManifest):
################################################################
if __name__ == "__main__":
+ # Report our own command line so that, in case of trouble, a developer can
+ # manually rerun the same command.
+ print('%s \\\n%s' %
+ (sys.executable,
+ ' '.join((("'%s'" % arg) if ' ' in arg else arg) for arg in sys.argv)))
+ # fmodstudio and openal can be used simultaneously and controled by environment
extra_arguments = [
dict(name='bugsplat', description="""BugSplat database to which to post crashes,
if BugSplat crash reporting is desired""", default=''),
+ dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'),
+ dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'),
]
try:
main(extra=extra_arguments)